合并具有重复项并对最后一列求和的行

时间:2017-02-15 10:10:38

标签: python-3.x loops pandas

我有这个输入文本文件

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;

到目前为止我取得的成绩是没有重复的线条,但我不得不删除区域列。

我用过这个:

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

1 个答案:

答案 0 :(得分: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 indexing使用duplicated删除重复项,然后汇总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