【问题标题】:Pandas transform: assign result to each element of group熊猫变换:将结果分配给组的每个元素
【发布时间】:2020-04-13 11:15:24
【问题描述】:

我目前正在使用 pandas groupby 和 transform 为每个组(一次)计算 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 的解决方案具有更高的优先级。

【问题讨论】:

  • 您的意思是转换中lambda 的输出返回每行的向量还是与组中的行数不同大小的向量?
  • 它计算一个向量,这应该是组中每个元素的结果。这个向量的大小是固定的(并且独立于组 len)。
  • 您不关心结果向量将分配给组的哪些行。例如,结果向量的大小为 3,组的大小为 30 行,如果将 3 个值分配给组的前 3 行或后 3 行或随机 3 行,是否可以?

标签: python pandas numpy data-structures


【解决方案1】:

有时使用转换很痛苦如果这对您来说不是问题,我建议您使用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]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-16
    • 1970-01-01
    • 1970-01-01
    • 2020-07-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多