繁体   English   中英

如何按关键字比较具有不同列数和行数的两个不同 CSV 文件?

[英]How to compare two different CSV files with different number of columns and rows by keyword?

不使用 diff 选项。

我有两个不同的 CSV 文件(我知道标题栏的名称)- old.csv 和 new.csv。 它们具有不同数量的行和列。 CSV 文件可以包含数字、字符串、字符和特殊字符。 例如:

旧的.csv

     round    date  first  second  third  fourth  fifth  sixth
1     2  2021.04      2    45e69     10    16      4565   37
2     3  2021.04      4      15    456as  df924     35   4N320
4     5  2021.03      4    43!d9    23      26      29     33

新的.csv

     round    date  first  second  third  fourth  fifth  sixth
0     1  2021.04      1      14     15      24      40     41
1     2  2021.04      2    45e69    10      16     4565    37
2     3  2021.04      4      15    456as   df924    35    4N320
3     4  2021.03     10      11     20      21     24325   41
5     6  2021.03    4321       9   2#@6     28     34350   41

两个 CSV 的第 1 行和第 2 行是相同的。

现在,我想打印出 new.csv 与 old.csv 之间的区别。 我只想打印 new.csv 文件中的新行。 像那样:

结果.csv

     round    date  first  second  third  fourth  fifth  sixth
0     1  2021.04      1     14     15      24     40     41
3     4  2021.03     10     11     20      21     24325  41
5     6  2021.03    4321    9     2#@6     28     34350  41

数行是为了便于阅读。 我希望标题列将保留在 result.csv 文件中。

我认为在这里可能有所帮助的选项是使用关键字。 例如,按“第一”和“第五”列比较两个 CSV 文件 - 如果其中一列不相同,则在 result.csv 文件中打印。

有一个你会发现有用的库: csv-diff

您可以从命令行使用它:

csv-diff one.csv two.csv --key=id --json

或作为 python 导入

from csv_diff import load_csv, compare
diff = compare(
    load_csv(open("one.csv"), key="id"),
    load_csv(open("two.csv"), key="id")
)

读取两个文件后使用集合而不是列表:

fileone = set(fileone)
filetwo = set(filetwo)

那么结果你可以得到一个对称的差异 - 除了fileonefiletwo集合中的元素之外,这两个集合的所有元素。

result = fileone.symmetric_difference(filetwo)

注意:标题行不包含在结果中,因为它在两个集合中是相同的

更新:文件二减去文件一:

result = filetwo.difference(fileone)

您需要单独检查要比较的每一列。 以下代码是如何执行此操作的一种选择。

import pandas as pd

def getLinesOnlyInA(dfa, dfb, result):
    # iterate over all lines in file a
    for index1, row1 in dfa.iterrows():
        aLineIsEqual = False
        # iterate over all lines in file b
        for index2, row2 in dfb.iterrows():
            thisLineIsDifferent = False
            # for each column, check if they are different
            for column in columns:
                if row1[column] != row2[column]:
                    thisLineIsDifferent = True
                    # ionly continue when the fields are the same
                    break
            if not thisLineIsDifferent:
                aLineIsEqual = True
                # only continue when no equal line was found
                break
        # when no equal line was found, add that line to the result
        if not aLineIsEqual:
            result.append(row1)
            
            
df1 = pd.read_csv('file1.csv')
df2 = pd.read_csv('file2.csv')
columns = ['round', 'first', 'fifth']     # columns to be compared
results = []

getLinesOnlyInA(df1, df2, results)        # find all lines only existing in file 1
getLinesOnlyInA(df2, df1, results)        # find all lines only existing in file 2
dfResult = pd.DataFrame(results)          # cast all lines into a dataframe

print(dfResult.to_string())   
dfResult.to_csv('result.csv', sep=',')

结果:

   round     date  first second third fourth  fifth sixth
2      5  2021.03      4  43!d9    23     26     29    33
0      1  2021.04      1     14    15     24     40    41
3      4  2021.03     10     11    20     21  24325    41
4      6  2021.03   4321      9  2#@6     28  34350    41

如果一个文件包含较少的列(例如, file1不包含date列),这仍然有效并导致:

   round  first second third fourth  fifth sixth     date
2      5      4  43!d9    23     26     29    33      NaN
0      1      1     14    15     24     40    41  2021.04
3      4     10     11    20     21  24325    41  2021.03
4      6   4321      9  2#@6     28  34350    41  2021.03

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM