熊猫变换:将结果分配给组中的每个元素

时间:2020-04-12 22:58:47

标签: python pandas numpy data-structures

我目前正在使用pandas groupby并进行变换以计算每个组的smth(一次),然后将结果分配给该组的每一行。 如果计算结果是标量,则可以这样获得:

df['some_col'] = df.groupby('id')['some_col'].transform(lambda x:process(x))

问题是我的计算结果是 vector ,而pd试图对结果组进行逐元素分配结果矢量(引用pandas docs):

转换函数必须: 返回与组块大小相同或可广播到组块大小的结果(例如,标量,grouped.transform(lambda x:x.iloc [-1]))。

我可以对外部函数进行硬编码,创建一个组大小的列表,其中将包含结果的副本(当前在python 3.6上,因此无法在lambda中使用赋值):

def return_group(x):
    result = process(x)
    return [result for item in x]

但是我认为有可能以某种方式“更智能”地解决这个问题。请记住,每个组只需要进行一次计算

是否可以强制pd.transform处理lambda函数的类似于数组的结果,例如标量(只需将其复制n次)?

对于任何建议将不胜感激。

P。 S.我知道,可以使用apply和join的组合来解决原始需求,但是在我的情况下,带有transform的解决方案具有更高的优先级。

1 个答案:

答案 0 :(得分:0)

有时转换很麻烦,如果这对您来说不是问题,我建议您使用groupby + a left pd.merge,例如以下示例:

import pandas as pd
df = pd.DataFrame({"id":[1,1,2,2,2],
                   "col":[1,2,3,4,5]})

# this return a list for every group
grp = df.groupby("id")["col"]\
        .apply(lambda x: list(x))\
        .reset_index(name="out")

#  Then you merge it to the original df
df = pd.merge(df, grp, how="left")

然后print(df)返回

   id  col        out
0   1    1     [1, 2]
1   1    2     [1, 2]
2   2    3  [3, 4, 5]
3   2    4  [3, 4, 5]
4   2    5  [3, 4, 5]