插入行作为GROUPBY操作的结果到原始数据帧
例如,我有一个熊猫数据框如下:插入行作为GROUPBY操作的结果到原始数据帧
col_1 col_2 col_3 col_4
a X 5 1
a Y 3 2
a Z 6 4
b X 7 8
b Y 4 3
b Z 6 5
而且我想,在COL_1每个值,在col_3添加值和COL_4(以及更多列),它们与col_2中的X和Z相对应,并使用这些值创建一个新行。所以输出会如下:
col_1 col_2 col_3 col_4
a X 5 1
a Y 3 2
a Z 6 4
a NEW 11 5
b X 7 8
b Y 4 3
b Z 6 5
b NEW 13 13
而且,有可能是在COL_1更多的价值,这将需要相同的待遇,所以我不能明确地引用“A”和“B”。我试图使用groupby('col_1')和apply()的组合,但是我无法使其工作。我已经足够接近下面的内容了,但是我无法在col_2中添加“新”,并将原始值(a或b等)保留在col_1中。
df.append(df[(df['col_2'] == 'X') | (df['col_2'] == 'Z')].groupby('col_1').mean())
谢谢。
如果你能保证X
和Z
一组中只出现一次,你可以使用一个groupby
和pd.concat
操作:
new = df[df.col_2.isin(['X', 'Z'])]\
.groupby(['col_1'], as_index=False).sum()\
.assign(col_2='NEW')
df = pd.concat([df, new]).sort_values('col_1')
df
col_1 col_2 col_3 col_4
0 a X 5 1
1 a Y 3 2
2 a Z 6 4
0 a NEW 11 5
3 b X 7 8
4 b Y 4 3
5 b Z 6 5
1 b NEW 13 13
@COLDSPEED,效果很好。我现在将如何应用自定义函数而不是sum()。所以,如果我需要用X除以Z例如? – Saturate
@Saturate我认为这有点困难。我认为你需要在内部使用拉姆达来进行分组。你可以打开另一个问题吗? –
下面的代码做的:
import pandas as pd
def sum_group(df):
dfxz = df[df.col_2.isin(['X','Z'])]
sum_row = pd.Series(
[
df.col_1.iloc[0],
'NEW',
dfxz.col_3.sum(),
dfxz.col_4.sum()
], index = dfxz.columns)
return df.append(sum_row, ignore_index=True)
df = pd.DataFrame([['a', 'X', 5, 1],
['a', 'Y', 3, 2],
['a', 'Z', 6, 4],
['b', 'X', 7, 8],
['b', 'Y', 4, 3],
['b', 'Z', 6, 5]],
columns = ['col_1','col_2','col_3','col_4'])
df = df.groupby('col_1').apply(
sum_group,
).reset_index(drop=True)
print df
的apply
groupby
对象的方法调用返回数据帧的函数sum_group
。数据帧然后连接成单个数据帧。 sum_group
将输入数据帧与另一行sum_row
并列,其中包含根据所述标准缩减版本的数据帧。
你能保证X和Z只出现在一个组中吗? –
是的,在col_1中每个值总是3行,col_2中的X,Y和Z只有一次。 col_4之后的列数不确定,但它总是一个列,需要按照与col_3和col_4相同的方式进行处理,即X和Z的总和。 – Saturate