【问题标题】:Merge csv's with some common columns and fill in Nans将 csv 与一些常用列合并并填写 Nans
【发布时间】:2015-12-13 16:51:20
【问题描述】:

我有几个 csv 文件(都在一个文件夹中),它们有共同的列,但也有不同的列。它们都包含 IP 列。数据看起来像

文件_1.csv

a,IP,b,c,d,e
info,192.168.0.1,info1,info2,info3,info4

文件_2.csv

a,b,IP,d,f,g
info,,192.168.0.1,info2,info5,info6

如您所见,文件 1 和文件 2 对 d 列的内容存在分歧,但我不介意它保存信息的文件来自哪个文件。我已经尝试过 pandas.merge ,但是这会返回 192.168.0.1 的两个单独条目,其中 NaN 在文件 1 中的列中而不是在文件 2 中,反之亦然。有谁知道这样做的方法吗?

编辑 1:

所需的输出应如下所示:

输出

a,IP,b,c,d,e,f,g   
info,192.168.0.1,info1,info2,info3,info4,info5,info6

我希望所有行的输出都像这样,而不是文件 1 中的每个项目都在文件 2 中,反之亦然。

编辑 2:

文件 1 中存在但文件 2 中不存在的任何 IP 地址在输出文件的任何唯一列中都应具有空白或不可用值。例如,在输出文件中,对于文件 1 中存在但文件 2 中不存在的 IP 地址,f 列和 g 列将为空。类似地,对于文件 2 中而不是文件 1 中的 IP,c 列和 e 列将为空在输出文件中。

【问题讨论】:

  • 能否包含您希望输出合并后的样子?
  • 已编辑以包含所需的输出
  • 我已经修复了 6 列和 5 个值,我想保留所有信息,所以 a 和 b 必须保留
  • 两个文件的IP地址是否相同?
  • 不是每个条目,但有些是

标签: python csv pandas merge


【解决方案1】:

本案例:

IP_address 设置为索引列,然后使用combine_first() 填充data_frame 中的一个洞,该data_frame 是所有IP_address 和列的并集。

import pandas as pd
#read in the files using the IP address as the index column
df_1 = pd.read_csv('file1.csv', header= 0, index_col = 'IP')
df_2 = pd.read_csv('file2.csv', header= 0, index_col = 'IP')
#fill in the Nan
combined_df = df_1.combine_first(df_2)
combined_df.write_csv(path = '', sep = ',')

编辑:将采用索引的联合,因此我们应该将 IP 地址放在索引列中,以确保读取两个文件中的 IP 地址。

combine_first() 其他情况:

正如documentation 所述,如果两个文件中的相同 IP 地址的列的非空信息存在冲突(例如上述示例中的column d),您只需小心。在df_1.combine_first(df_2) 中,df_1 具有优先级,column d 将设置为来自df_1 的值。既然你说过,在这种情况下你将从哪个文件中提取信息并不重要,这不是这个问题的关注点。

【讨论】:

  • 这是否也允许 b 包含不在 a 中的列仍包含在输出中?
  • @DanielPrinsloo 我已经编辑了我的答案,因此不在 b 中的列将包含在输出中,并且将读入两个文件中 IP 地址的联合。
  • 谢谢你在完整的文件中给这个通行证,让你知道它是怎么回事
  • 我正在尝试将结束数据帧写入 csv 以供读取,但是如果我在组合 df_2 后使用 df_1.to_csv('output.csv',sep=','),它只包含来自 df_1 的信息到 df_1
  • 你先生太棒了,重新树立了我对 python 社区的信心,谢谢。
【解决方案2】:

我认为一个简单的字典应该可以完成这项工作。假设您已将每个文件的内容读入列表file1file2,这样:

file1[0] = [a,IP,b,c,d,e]
file1[1] = [info,192.168.0.1,info1,info2,info3,info4]
file2[0] = [a,b,IP,d,f,g]
file2[1] = [info,,192.168.0.1,info2,info5,info6]

(在每个条目周围加上引号)。以下应该做你想做的事:

new_dict = {}

for i in range(0, len(file2[0]):
    new_dict[file2[0][i]] = file2[1][i]

for i in range(0, len(file1[0]):
    new_dict[file1[0][i]] = file1[1][i]

output = [[],[]]
output[0] = [key for key in new_dict]
output[1] = [new_dict[key] for key in output[0]]

那么你应该得到:

output[0] = [a,IP,b,c,d,e,f,g]
output[1] = [info,192.168.0.1,info1,info2,info3,info4,info5,info6]

【讨论】:

  • 那么要写入 csv 文件,我只需遍历输出?
猜你喜欢
  • 1970-01-01
  • 2021-11-23
  • 2017-10-25
  • 2012-08-16
  • 1970-01-01
  • 2016-03-25
  • 1970-01-01
  • 2016-01-15
  • 1970-01-01
相关资源
最近更新 更多