首页 > 解决方案 > 使用 Python 根据列值合并和删除多行

问题描述

我有一个像这样的数据框:

Task  ID  Value  Sno
 A    A1    5     1
 A    A1    2     2
 B    A1    4     3
 A    A1    1     4
 A    B1    10    5
 C    B1    3     6
 D    B1    5     7
 D    B1    2     8
 D    B1    12    9
 E    C1    25    10

预期的输出应该看起来像

Task  ID  Value  Sno
 A    A1    7    1,2
 B    A1    4     3
 A    A1    1     4
 A    B1    10    5
 C    B1    3     6
 D    B1    19   7,8,9
 E    C1    25    10

因此,对于 ID 相同的每条记录,必须合并相同的连续“任务”并添加“值”。我的方法在下面列出,但它没有考虑相同“任务”出现两次以上的情况(示例中的“D”任务)。另外,合并后无法删除行,不知道为什么。

    for j in range(len(df)-1):
    if(df.loc[j,'Task']==df.loc[j+1, 'Task'] and df.loc[j,'ID']==df.loc[j+1, 'ID']):
        df.loc[j, 'Value'] = df.loc[j, 'Value'] + df.loc[j+1, 'Value']
        df.loc[j, 'ID'] = str(df.loc[j, 'ID']) + "," + str(df.loc[j+1, 'ID'])
        df.drop([j+1])

标签: pythonpandasdataframeaggregate

解决方案


非常类似于 groupby 和聚合连接。但是,您必须首先创建一个帮助列来识别连续的组:

u = df[['Task','ID']]
g = u.ne(u.shift()).any(1).cumsum()

d = {"Value":"sum","Sno":lambda x: ','.join(x.astype(str))}
#d = {"Value":"sum","Sno":lambda x: ','.join([str(i) for i in x])}

out = df.groupby(['Task','ID',g]).agg(d).droplevel(-1).reset_index()

print(out)

  Task  ID  Value    Sno
0    A  A1      7    1,2
1    A  A1      1      4
2    A  B1     10      5
3    B  A1      4      3
4    C  B1      3      6
5    D  B1     19  7,8,9
6    E  C1     25     10

推荐阅读