【问题标题】:Comparing two CSV files and exporting the differences and similarities in Python?比较两个 CSV 文件并导出 Python 中的异同?
【发布时间】:2018-07-21 09:52:43
【问题描述】:

大家好,所以我在尝试使用两个单独的 CSV 文件来完成我需要的事情时遇到了一些麻烦。我发现一些散布在网络上的脚本可以做我想做的事,但不完全是。我不再有我尝试过的代码,因为我已经多次删除不同的代码,以至于我已经盯着一个空白的 py 文件看了很长时间。首先是 CSV 文件。

netscan.csv(包含计算机名称和序列号,有正确的数据,有型号)

Name        Serial   Models
computer1   serial1  model1
computer2   serial2  model2
computer3   serial3  model3
computer4   serial4  model4
...         ...

computer_list.csv(包含计算机名称和序列号,名称正确,名称不在 netscan.csv 中,没有型号,序列号错误)

Name        Serial    Models
computer1   serialZ
computerH   serialN/A
computer3   serialQ
computer4   serialX
computer2   serialM
computerP   serialN/A

所以我想做的是查看这两个文件,如果Name 列中的值匹配,我希望它将netscan.csv 中的行打印到一个新文件中,并对每一行执行此操作。之后,我希望它采用所有不存在的(例如 netscan.csv 中不存在的 computerH)并将它们添加到更新的正确信息下的新 csv 中。像这样的:

Name        Serial   Models
computer1   serial1  model1
computer2   serial2  model2
computer3   serial3  model3
computer4   serial4  model4
computerH   serialN/A
computerP   serialN/A

我已经尝试过合并、for 循环、写入行等,但我现在不知道如何才能做到这一点。任何帮助将不胜感激。

编辑:@unutbu 我从你的代码中得到的基本上是

Name     Serial    Models
computer1   serial1  model1
computer2   serial2  model2
computer3   serial3  model3
computer4   serial4  model4
computerH   serialN/A
computerP   serialN/A
computer2   serialN/A
computer3   serialN/A
computer4   serialN/A

因此,尽管几乎所有内容都正确,但 computer_list.csv 中仍有重复的 Name 行,如果它们被正确的信息替换,则需要将其删除。所以我想查找具有重复名称的行,如果 Serial 为 serialN/A,则将其删除。希望这更有意义。

【问题讨论】:

  • netscan.csv 或computer_list.csv 中是否存在重复行? (重复是指具有相同 Name 的行,不一定是 SerialModels 值。)
  • 也不,重复项仅在result.csv 中,我需要删除的重复项来自错误信息所在的computer_list.csv。我正在考虑让每一行都有一个重复的Name 值,然后删除它if Serial 列是 N/A,但我不太确定如何语法。想法?

标签: python pandas csv automation analysis


【解决方案1】:

您可以合并netscancomputer 数据帧,然后用SerialN/A 填充Serial 列中的缺失值。

import pandas as pd
netscan = pd.read_csv('netscan.csv')
computer = pd.read_csv('computer_list.csv', usecols=['Name'])
for df in [netscan, computer]:
    df['Name'] = df['Name'].str.rstrip()
result = pd.merge(netscan, computer, on='Name', how='outer')
result['Serial'] = result['Serial'].fillna('SerialN/A')
result.to_csv('result.csv', index=False)
print(result)

生成一个 CSV 文件 (result.csv),其中包含

Name,Serial,Models
computer1,serial1,model1
computer2,serial2,model2
computer3,serial3,model3
computer4,serial4,model4
computerH,SerialN/A,
computerP,SerialN/A,

【讨论】:

  • 这让我非常接近,但计算机列表文件中仍有重复项,例如Name,Serial,Modelscomputer1,serial1,model1computer2,serial2,model2computer3,serial3,model3computer4,serial4,model4computerH,SerialN/A,computerP,SerialN/A,computer1,SerialN/A@ 987654336@ 有没有办法删除 NA 重复,但保留好的?
  • 在 cmets 中读取数据/代码非常困难。请编辑您的问题以显示导致问题的netscan.csvcomputer_list.csv 的内容。你是说computer_list.csv 包含不止一行具有相同的Name
  • 我在上面的代码中添加了computer['Name'] = computer['Name'].drop_duplicates()这一行。我猜computer_list.csv 中有一条或多条重复的行,这会导致result.csv 中的重复。 (AFAICS,如果netscan.csvcomputer_list.csv 中没有重复项,那么result 中应该没有重复项。)
  • 是的,之后没有任何变化。三重检查了这两个文件,它们每个都没有任何重复的名称。我能想到摆脱这种情况的唯一方法是列出具有重复名称的行,如果串行选项卡显示为 N/A,则将其删除。
  • 我讨厌添加 mask(见上文),因为我的行为与我认为 Pandas 应该的行为方式背道而驰。但作为一个务实的问题,也许它会对你有所帮助。
【解决方案2】:

这可能有助于各种比较

import numpy as np
import pandas as pd
#file_name = "list.xlsx"
df = pd.DataFrame({'List1':[1,2,3,4,5,5,11,4],'List 2':[3,5,6,8,9,3,4,9]}, columns=['List1', 'List 2'])#pd.read_excel(file_name, sheetname=0)
print(df)
#df.to_excel("list1.xlsx", header=True, index=False)
df['Intersect']=pd.DataFrame(np.intersect1d(df['List1'], df['List 2'])) #unique common in both
df['commonin1']=df['List1'][np.in1d(df['List1'], df['List 2'])] #non unique common items of list 1
df['commonin2']=df['List 2'][np.in1d(df['List 2'], df['List1'])] #non unique common items of list 2
df['1not2']=pd.DataFrame(np.setdiff1d(df['List1'], df['List 2'])) #in list1 but not in list 2
df['2not1']=pd.DataFrame(np.setdiff1d(df['List 2'], df['List1'])) #in list 2 but not in list1
df['1not2NU']=df['List1'][~np.in1d(df['List1'], df['List 2'])] #in list1 but not in list 2 non unique
df['2not1NU']=df['List 2'][~np.in1d(df['List 2'], df['List1'])] #in list 2 but not in list1 non unique
df['exclusive']=pd.DataFrame(np.setxor1d(df['List1'], df['List 2'])) # in a and not b + in b but not a
df=pd.concat([df,pd.DataFrame(np.union1d(df['List1'], df['List 2']), columns=['Union'])], axis=1) # unique all
df

【讨论】:

    【解决方案3】:

    看看这个:

    import pandas as pd
    netscan = pd.read_csv('netscan.csv', header=0) # read netscan.csv and columns names are from the first row of your csv
    computer_list = pd.read_csv('computer_list.csv', header=0)
    
    # An inner merge keeps only row found in both pandas.DataFrame 
    computer_match = netscan.merge(right=computer_list, how='inner', on='Name', suffixes=('netscan_', 'computer_list_'))
    
    # Get list of Name of computers that matches
    match_list = computer_match.Name.unique().tolist()
    
    # Get characteristics of not matched computers
    computer_no_match = computer_list.loc[computer_list.Name.isin(match_list), :]
    
    # Finally, save everything to CSV
    computer_match.to_csv('computer_match.csv', index=False)
    computer_no_match.to_csv('computer_no_match.csv', index=False)
    

    【讨论】:

    • 这只会生成第一行有名称、序列号、型号的文件,没有其他信息。
    猜你喜欢
    • 2016-12-24
    • 1970-01-01
    • 2022-01-24
    • 2014-06-08
    • 1970-01-01
    • 2013-06-17
    • 2020-10-17
    • 2023-03-15
    • 2015-01-20
    相关资源
    最近更新 更多