【问题标题】:Merging lines that has duplicates and summing last column合并有重复的行并对最后一列求和
【发布时间】:2017-07-03 22:22:48
【问题描述】:

我有这个输入文本文件

1;2;29.02.2017;10.00-11.00;5;

1;2;29.02.2017;10.00-11.00;3;

1;3;02.02.2017;09.00-10.00;4;

1;3;03.02.2017;12.00-13.00;2;

1;3;28.02.2017;08.00-09.00;6;

1;3;29.02.2017;10.00-11.00;3;

1;3;29.02.2017;10.00-11.00;2;

1;3;29.02.2017;11.00-12.00;2;

1;3;29.02.2017;12.00-13.00;3;

10;11;28.02.2017;08.00-09.00;6;

10;11;28.02.2017;08.00-09.00;1;

10;12;02.02.2017;09.00-10.00;8;

10;12;28.02.2017;08.00-09.00;2;

10;12;28.02.2017;08.00-09.00;1;

用';'分隔的值如下面所述: 1- id_1(str), 2- id_2(str), 3- date(str), 4- time(str), 5- area(int)

作为输出,我需要一个包含输入行的文本文件,其中包含 1、2、3、4 个重复项和总面积。我需要删除没有重复的行,例如

1;2;29.02.2017;10.00-11.00;8;  (sum of 5 from line 1 and 3 from line 2)

1;3;29.02.2017;10.00-11.00;5;

10;11;28.02.2017;08.00-09.00;7;

10;12;28.02.2017;08.00-09.00;3;

到目前为止,我所取得的成就是删除了没有重复的行,但我不得不删除 area 列。

我用过这个:

seen = set()
for line1 in imp:
    line1_lower = line1.lower()
    if line1_lower in seen:
        print(line1)
    else:
        seen.add(line1_lower)

【问题讨论】:

    标签: python-3.x loops pandas


    【解决方案1】:

    您可以先使用read_csv 和参数names 来创建列名(如果csv 没有标题):

    import pandas as pd
    from pandas.compat import StringIO
    
    temp=u"""1;2;29.02.2017;10.00-11.00;5;
    1;2;29.02.2017;10.00-11.00;3;
    1;3;02.02.2017;09.00-10.00;4;
    1;3;03.02.2017;12.00-13.00;2;
    1;3;28.02.2017;08.00-09.00;6;
    1;3;29.02.2017;10.00-11.00;3;
    1;3;29.02.2017;10.00-11.00;2;
    1;3;29.02.2017;11.00-12.00;2;
    1;3;29.02.2017;12.00-13.00;3;
    10;11;28.02.2017;08.00-09.00;6;
    10;11;28.02.2017;08.00-09.00;1;
    10;12;02.02.2017;09.00-10.00;8;
    10;12;28.02.2017;08.00-09.00;2;
    10;12;28.02.2017;08.00-09.00;1;"""
    #after testing replace 'StringIO(temp)' to 'filename.csv'
    df = pd.read_csv(StringIO(temp), sep=";", names=['id_1','id_2','date','time','area','tmp'])
    
    print (df)
        id_1  id_2        date         time  area  tmp
    0      1     2  29.02.2017  10.00-11.00     5  NaN
    1      1     2  29.02.2017  10.00-11.00     3  NaN
    2      1     3  02.02.2017  09.00-10.00     4  NaN
    3      1     3  03.02.2017  12.00-13.00     2  NaN
    4      1     3  28.02.2017  08.00-09.00     6  NaN
    5      1     3  29.02.2017  10.00-11.00     3  NaN
    6      1     3  29.02.2017  10.00-11.00     2  NaN
    7      1     3  29.02.2017  11.00-12.00     2  NaN
    8      1     3  29.02.2017  12.00-13.00     3  NaN
    9     10    11  28.02.2017  08.00-09.00     6  NaN
    10    10    11  28.02.2017  08.00-09.00     1  NaN
    11    10    12  02.02.2017  09.00-10.00     8  NaN
    12    10    12  28.02.2017  08.00-09.00     2  NaN
    13    10    12  28.02.2017  08.00-09.00     1  NaN
    

    然后 groupby 和聚合 sizesum,最后使用 boolean indexing 删除重复项 - 获取大小大于 1 的值:

    cols = ['id_1','id_2','date','time']
    df = df.groupby(cols)['area'].agg(['size', 'sum'])
    df = df[df['size'] > 1].drop('size',axis=1).reset_index()
    print (df)
       id_1  id_2        date         time  sum
    0     1     2  29.02.2017  10.00-11.00    8
    1     1     3  29.02.2017  10.00-11.00    5
    2    10    11  28.02.2017  08.00-09.00    7
    3    10    12  28.02.2017  08.00-09.00    3
    

    另一种解决方案是先通过boolean indexingduplicated 删除重复项,然后聚合sum

    cols = ['id_1','id_2','date','time']
    mask = df.duplicated(cols, keep=False)
    df = df[mask].groupby(cols, as_index=False)['area'].sum()
    print (df)
       id_1  id_2        date         time  area
    0     1     2  29.02.2017  10.00-11.00     8
    1     1     3  29.02.2017  10.00-11.00     5
    2    10    11  28.02.2017  08.00-09.00     7
    3    10    12  28.02.2017  08.00-09.00     3
    

    【讨论】:

    • 感谢您的回复,我会尽快检查:)希望它会起作用,因为我花了很多时间考虑它
    • 是的,我也希望如此。检查一下,如果我的回答有帮助,请不要忘记accept。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2020-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-17
    相关资源
    最近更新 更多