根据第二个csv过滤一个csv

时间:2018-06-19 00:54:20

标签: python pandas

在读取两个CSV文件A和B后,我想删除B中的所有行 其前两列与A中任何一行的前两列不匹配。 然后将B保存到磁盘。

这是我到目前为止所做的:

 A =  pd.read_csv('A.csv', header=None)
 B = pd.read_csv('B.csv', header = None)
 for row_A in A.iterrows():
     foundMatch = False
     for row_B in B.iterrows():
         if (row_A[0] == row_B[0] and row_A[1] == row_B[1]) :
             foundMatch = True
             break
     if (!foundMatch)
         # delete row from B
  B.to_csv('B_filtered.csv', index=False, header=None)

2 个答案:

答案 0 :(得分:3)

IIUC,给出两个数据框:

dfa = pd.DataFrame({"col1": ["str{}".format(i) for i in range(10)], 
                   "col2": ["str{}".format(chr(i)) for i in range(97,107)]})

    col1    col2
0   str0    stra
1   str1    strb
2   str2    strc
3   str3    strd
4   str4    stre
5   str5    strf
6   str6    strg
7   str7    strh
8   str8    stri
9   str9    strj

dfb = pd.DataFrame({"col1": ["str0", "str1", "str1000"],
                    "col2": ["stra", "strb", "strc"]})

    col1    col2
0   str0    stra
1   str1    strb
2   str1000 strc

您可以先transform将前两列变为tuples(以及随后可出售的对象),然后使用isin检查df中是否存在此类对A,即

>>> dfa.transform(tuple, 1)
0    (str0, stra)
1    (str1, strb)
2    (str2, strc)
3    (str3, strd)
4    (str4, stre)
5    (str5, strf)
6    (str6, strg)
7    (str7, strh)
8    (str8, stri)
9    (str9, strj)

所以

df_final = dfb.loc[dfb.transform(tuple, 1).isin(dfa.transform(tuple, 1))]

给出了

    col1    col2
0   str0    stra
1   str1    strb

然后只保存to_csv

df_final.to_csv("result.csv")

(旁注:尽可能,尽量不要在pandas数据框中使用迭代。性能会很糟糕,你会失去这个库的真正功能)

答案 1 :(得分:1)

你也可以试试这个使用this article库的纯python解决方案:

from csv import reader
from csv import writer

with open('A.csv') as fileA, \
     open('B.csv') as fileB, \
     open('B_filtered.csv', 'w') as outB:

    csv_writer = writer(outB)

    readerA = reader(fileA)
    readerB = reader(fileB)

    # store first two columns of every row in file A
    A_map = {(col1, col2) for col1, col2, *_ in readerA}

    for col1, col2, *rest in readerB:

        # only write to csv if columns exist in map
        if (col1, col2) in A_map:
            csv_writer.writerow([col1, col2, *rest])