我目前正在使用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的解决方案具有更高的优先级。
答案 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]