Qua*_*sto 16 python transform pandas pandas-groupby
我有可以按预期工作的示例代码段:
import pandas as pd
df = pd.DataFrame(data={'label': ['a', 'b', 'b', 'c'], 'wave': [1, 2, 3, 4], 'y': [0,0,0,0]})
df['new'] = df.groupby(['label'])[['wave']].transform(tuple)
Run Code Online (Sandbox Code Playgroud)
结果是:
label wave y new
0 a 1 0 (1,)
1 b 2 0 (2, 3)
2 b 3 0 (2, 3)
3 c 4 0 (4,)
Run Code Online (Sandbox Code Playgroud)
如果不是,tuple我给出set, frozenset, dict,它会以类似的方式工作,但是如果给出,list我将得到完全出乎意料的结果:
df['new'] = df.groupby(['label'])[['wave']].transform(list)
label wave y new
0 a 1 0 1
1 b 2 0 2
2 b 3 0 3
3 c 4 0 4
Run Code Online (Sandbox Code Playgroud)
有一种变通方法以获得预期的结果:
df['new'] = df.groupby(['label'])[['wave']].transform(tuple)['wave'].apply(list)
label wave y new
0 a 1 0 [1]
1 b 2 0 [2, 3]
2 b 3 0 [2, 3]
3 c 4 0 [4]
Run Code Online (Sandbox Code Playgroud)
我考虑过可变性/不变性(列表/元组),但是对于集合/冻结集,它是一致的。
问题是为什么它会以这种方式工作?
我以前也遇到过类似的问题。我认为潜在的问题是,当列表中的元素数量与组中的记录数量匹配时,它会尝试解压缩列表,以便列表中的每个元素都映射到组中的一条记录。
例如,这将导致列表解包,因为列表的len与每个组的长度匹配:
df.groupby(['label'])[['wave']].transform(lambda x: list(x))
wave
0 1
1 2
2 3
3 4
Run Code Online (Sandbox Code Playgroud)
但是,如果列表的长度与每个组的长度都不相同,那么您将获得所需的行为:
df.groupby(['label'])[['wave']].transform(lambda x: list(x)+[0])
wave
0 [1, 0]
1 [2, 3, 0]
2 [2, 3, 0]
3 [4, 0]
Run Code Online (Sandbox Code Playgroud)
我认为这是列表拆包功能的副作用。
我认为这是熊猫的一个错误。您可以在他们的 github页面上开票吗?
起初我想,这可能是,因为list只是没有正确处理作为 的参数.transform,但如果我这样做:
def create_list(obj):
print(type(obj))
return obj.to_list()
df.groupby(['label'])[['wave']].transform(create_list)
Run Code Online (Sandbox Code Playgroud)
我得到了同样意想不到的结果。然而,如果agg使用该方法,它会直接起作用:
df.groupby(['label'])['wave'].agg(list)
Out[179]:
label
a [1]
b [2, 3]
c [4]
Name: wave, dtype: object
Run Code Online (Sandbox Code Playgroud)
我无法想象这是有意的行为。
顺便提一句。我还发现不同的行为很可疑,如果您将元组应用于分组系列和分组数据框,就会出现这种情况。例如,如果transform应用于一系列而不是 DataFrame,则结果也不是包含列表的系列,而是包含以下内容的系列ints(请记住,[['wave']]它创建的单列数据帧transform(tuple)确实返回了元组):
df.groupby(['label'])['wave'].transform(tuple)
Out[177]:
0 1
1 2
2 3
3 4
Name: wave, dtype: int64
Run Code Online (Sandbox Code Playgroud)
如果我再次这样做,agg而不是transform它对两者都有效['wave']并且[['wave']]
我在 ubuntu X86_64 系统上使用版本 0.25.0 进行测试。
| 归档时间: |
|
| 查看次数: |
605 次 |
| 最近记录: |