我对示例 csv 文件有以下要求,如下所示,
colA colB NewCol
1 val1 val1
1 val2 val1 + val2
1 val3 val1 + val2 + val3
2 val4 val4
2 val5 val4 + val5
2 val6 val4 + val5 + val6
3 val7 val7
3 val8 val7 + val8
3 val9 val7 + val8 + val9
我想向 df 添加一个新列,以便它仅为相同的 ID 值添加连续的 colB 值。列 B 可以是整数或字符串。
使用groupby
+cumsum
:
df['NewCol'] = df.groupby('colA')['colB'].cumsum()
对于字符串求和,您可以使用列表推导式groupby
:
df = df.sort_values('colA')
df['C'] = [''.join(g.iloc[:i+1].values)
for _, g in df.groupby('colA')['colB']
for i in range(len(g.index))]
print(df)
colA colB C
0 1 val1 val1
1 1 val2 val1val2
2 1 val3 val1val2val3
3 2 val4 val4
4 2 val5 val4val5
5 2 val6 val4val5val6
6 3 val7 val7
7 3 val8 val7val8
8 3 val9 val7val8val9
解释
- 首先通过
for _, g in df.groupby(...)[...]
迭代groupby
元素。我们忽略索引_
,因为我们只对值感兴趣。 - 然后迭代
range(len(g.index))
,即迭代组中的项目数。 - 对前
i
值应用''.join
。我们使用g.iloc[:i+1]
来提取组中的前i
值。 - 将上述所有内容包装在一个嵌套列表理解中。
使用np.cumsum
或pd.Series.cumsum
完美地处理数字和字符串:
df['NewCol'] = df.groupby('colA')['colB'].apply(np.cumsum)
或:
df['NewCol'] = df.groupby('colA')['colB'].apply(pd.Series.cumsum)
print (df)
colA colB NewCol
0 1 val1 val1
1 1 val2 val1val2
2 1 val3 val1val2val3
3 2 val4 val4
4 2 val5 val4val5
5 2 val6 val4val5val6
6 3 val7 val7
7 3 val8 val7val8
8 3 val9 val7val8val9