【问题标题】:Is there a faster way to check the similar data value in a column from csv file using python?有没有更快的方法来使用 python 从 csv 文件中检查列中的相似数据值?
【发布时间】:2018-02-27 08:53:00
【问题描述】:

我有 2 个 csv 文件(假设为 CSV-1.csv 和 CSV-2.csv),每个文件包含一万多个数据。这 2 个文件有 2 个相同的列,即 'filename' 和 'number_of_changes'。我的目的是根据文件名比较这两个文件。如果 CSV-1 中的文件名也在 CSV-2 中,则检查“number_of_changes”列。如果这 2 个 csv 文件之间具有相同文件名的更改数量不同,则将此数据存储在具有 3 列的新 csv 文件中(假设 New_CSV.csv)。但是如果这两个文件中的文件名和 number_of_changes 相同,则传递它(不要存储在新的 csv 中)。 假设我的 CSV 文件:

CSV-1.csv

filename     |  number_of_changes
---------------------------------
A            |   20
B            |   10
C            |   10
E            |    5
F            |   15

CSV-2.csv

filename     |  number_of_changes
A            |   20
B            |   15
D            |   30
E            |   10

我需要从上面的 2 个文件中创建新的 csv 文件 (New_CSV.csv):

filename     |  number_of_changes-1 | number_of_changes-2
----------------------------------------------------------
B            |   10                 |  15
C            |   10                 |   0
D            |    0                 |  30
E            |    5                 |  10
F            |   15                 |   0

到目前为止,我已经编写了代码:

import pandas as pd

cols = ['filename','number_of_changes']
data1 = pd.read_csv('CSV-1.csv')
data2 = pd.read_csv('CSV-2.csv')
df1 = data1[cols]
df2 = data2[cols]

lshist = []
for x in range(0,len(df1)-1):
    lshist.append(list(df1.iloc[x]))

lsmyers = []
for y in range(0,len(df2)-1):
    lsmyers.append(list(df2.iloc[y]))

with open('New_CSV.csv', 'w') as csvfile:
    header = ['filename', 'number_of_changes-1', 'number_of_changes-2']
    writers = csv.writer(csvfile, delimiter=',')
    writers.writerow(header)
    for fn in range(1,len(lshist)-1):
        tmp = []
        fnhist = lshist[fn][0]
        for x in range(0,len(lsmyers)-1):
            sys.stdout.write('\rSearching in myers : %i' % (x+1) + ' out of %i' % (len(lsmyers)-1) + ' in % i' % (fn) + ' out of %i' % (len(lshist)-1) + ' in histogram')
            sys.stdout.flush()
            if fnhist != lsmyers[x][0]:
                pass
            else:
                if lshist[fn][1] == lsmyers[x][1]:
                    pass
                else:
                    tmp = [fnhist,lshist[fn][1],lsmyers[x][1]]

        writers.writerow(tmp)

当我运行代码时,它仅适用于两个 CSV 文件中的文件。但它不适用于不在其他 CSV 文件中的文件。此外,一个缺点是当数据非常大时需要很长时间。那么,有没有更快更好的算法呢?请你的建议。谢谢。

【问题讨论】:

    标签: python csv dataframe


    【解决方案1】:

    确实有一种更简单的方法 - merge 将数据框合二为一。基本上是这样的:

    df1 = pd.read_csv("CSV-1.csv")
    df2 = pd.read_csv("CSV-2.csv")
    df3 = df1.merge(df2, on="filename", how="left")
    df3.fillna(0, inplace=True)
    # df3 would contain the following dataframe
    ###########
    # filename  number_of_changes_x number_of_changes_y
    # 0 A   20  20.0
    # 1 B   10  15.0
    # 2 C   10  0.0
    # 3 E   5   10.0
    # 4 F   15  0.0
    

    基本上将两个数据帧合并为一个,并用 0 填充 np.NaN 值。根据您的需要,您可能需要将第二列转换为 int。此外,如果您需要更改列名,请使用rename 方法。

    【讨论】:

      【解决方案2】:

      你需要这样的东西

      df1 = pd.read_csv('CSV-1.csv')
      df2 = pd.read_csv('CSV-2.csv')
      

      合并两个数据框

      df3 = df1.merge(df2, on="filename", how="outer",suffixes=('-1', '-2'))
      

      删除更改次数相同的行

      df3 = df3[df3['number_of_changes-1'] != df3['number_of_changes-2']]
      

      用 0 填充 NA 并按文件名排序

      df3.fillna(0, inplace=True)
      df3 = df3.sort_values(by ='filename').reset_index(drop=True)
      

      输出:

          filename    number_of_changes-1     number_of_changes-2
      0       B       10.0                    15.0
      1       C       10.0                     0.0
      2       D        0.0                    30.0
      3       E        5.0                    10.0
      4       F       15.0                     0.0
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-12-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-15
        • 2013-10-10
        • 2020-07-31
        相关资源
        最近更新 更多