簡體   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