将函数应用于 pandas groupby 数据帧中的所有列

时间:2021-04-29 08:36:05

标签: python pandas dataframe pandas-groupby apply

我有以下数据框(我们称之为 data):

id | type | val1 | val2 |
-------------------------
1  |  A   | 10.1 | 11.0 |
1  |  B   | 10.5 | 11.2 |
2  |  A   | 10.7 | 10.9 |
2  |  B   | 10.6 | 11.1 |
3  |  A   | 10.3 | 10.5 |
3  |  B   | 10.4 | 11.3 |

并且我想为每个 A 为每个 B 获取类型 AB (id-valX) 之间的差异} 列,即我希望结果是:

id | val1 | val2 |
------------------
1  | -0.4 | -0.2 |
2  |  0.1 | -0.2 |
3  | -0.1 | -0.8 |

我能做到这一点的唯一方法是定义一个函数:

def getDelta(df, valName):
    return df[ df['type']=='A' ][valName].values[0] - df[ df['type']=='B' ][valName].values[0]

并将其分别应用于每一列:

data.groupby('id').apply(getDelta,valName='val1')

然后合并结果以获得我想要的。

有没有更有效的方法来做到这一点?最后,我想将函数应用于分组数据帧的列的子集,但此函数必须考虑另一列的值。

3 个答案:

答案 0 :(得分:2)

就目前而言,您可以使用 np.subtract.reduce,假设在所有情况下 'A' 出现在 'B' 之前,并且没有重复项:

df.groupby("id", sort = False).agg(np.subtract.reduce).reset_index()

   id  val1  val2
0   1  -0.4  -0.2
1   2   0.1  -0.2
2   3  -0.1  -0.8

答案 1 :(得分:1)

您可以旋转数据框:

x = df.pivot(index="id", columns="type", values="val1")
y = df.pivot(index="id", columns="type", values="val2")

df = pd.concat([x["A"] - x["B"], y["A"] - y["B"]], axis=1).rename(
    columns={0: "val1", 1: "val2"}
)
print(df)

打印:

    val1  val2
id            
1   -0.4  -0.2
2    0.1  -0.2
3   -0.1  -0.8

答案 2 :(得分:1)

您可以 groupby() 您的 ID 列并在您的 diff(-1) 列上使用 valX。将操作包装在 concat() 中,您会得到您想要的结果吗。

df.set_index('id',inplace=True)
pd.concat([df.groupby(['id'])[df.filter(like='val').columns.tolist()].diff(-1).dropna()]).reset_index()

   id  val1  val2  val3
0   1  -0.4  -0.2  -3.1
1   2   0.1  -0.2  17.0
2   3  -0.1  -0.8   1.5

我添加了一个额外的 valX 只是为了说明目的。

相关问题