首页 > 解决方案 > 熊猫转换列表的不一致行为

问题描述

我有按预期工作的示例片段:

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)

结果是:

  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,)

它的工作原理类似,如果不是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

有一种解决方法可以获得预期的结果:

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]

我考虑了可变性/不变性(列表/元组),但对于 set/frozenset 它是一致的。

问题是为什么它以这种方式工作?

标签: pythonpandastransformpandas-groupby

解决方案


我以前遇到过类似的问题。我认为潜在的问题是当列表中的元素数量与组中的记录数匹配时,它会尝试解包列表,以便列表的每个元素映射到组中的记录。

例如,这将导致列表解包,因为列表的 len 与每个组的长度匹配:

df.groupby(['label'])[['wave']].transform(lambda x: list(x))
    wave
0   1
1   2
2   3
3   4

但是,如果列表的长度与每个组不同,您将获得所需的行为:

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]

我认为这是列表解包功能的副作用。


推荐阅读