Pandas按组分组并生成项目集合

22

我正在使用pandas的groupby功能,并希望将函数应用于组中项目的集合。

以下代码会导致出现TypeError: 'type' object is not iterable

df = df.groupby('col1')['col2'].agg({'size': len, 'set': set})

但是以下代码有效:

def to_set(x):
    return set(x)
    
df = df.groupby('col1')['col2'].agg({'size': len, 'set': to_set})

在我看来,这两种表达方式很相似,为什么第一种行不通呢?

4个回答

21

更新

  • 直到pandas版本0.22,这仍然是个问题。
  • 从pandas版本1.1.2开始,这不再是一个问题。 聚合set不会导致TypeError:'type' object is not iterable
    • 不确定功能何时更新。

原始回答

这是因为settypetype,而to_settypefunction

type(set)
<class 'type'>

def to_set(x):
    return set(x)

type(to_set)

<class 'function'>
根据文档.agg()方法需要:
- arg: function 或者 dict - 聚合组所使用的函数。如果是一个函数,则必须能够处理传入的DataFrame或通过DataFrame.apply传递; - 如果传递了一个字典,则键必须是DataFrame列名。 - 可接受的组合方式有: - string搜索的cython化函数名称 - function - 函数列表list - 列 -> 函数字典dict - 名称 -> 函数字典的嵌套dict

为了完整性,它会引发一个错误 TypeError: 'type' object is not iterable,这可能是因为如果您没有传递一个函数,它会期望一个函数列表。 - ayhan

11

尝试使用:

df = df.groupby('col1')['col2'].agg({'size': len, 'set': lambda x: set(x)})

对我来说没问题。


5
如果你像你刚才那样简单地写了一句话,就必须加上上下文来解释你做了什么以及为什么有效。跟随用户Stefan的示例,会比仅仅用一句话更容易获得同情和赞同。你必须让它对未来的读者有所启示,使他们能够从中学习。 - ZF007
2
'set': lambda x: set(x) can be replaced with 'set': set - Vlas Sokolov

5

如果你遇到以下错误,请升级至较新版本的Pandas

SpecificationError: nested renamer is not supported

df = df.groupby('col1')['col2'].agg(size= len, set= lambda x: set(x))

1
set= lambda x: set(x) can be simplified to set=set - Vlas Sokolov

0

如果使用.agg({'set': set}),请更新Pandas版本至1.3.3,否则会产生以下错误:

TypeError: Unable to infer the type of the field set

即使简单地使用先前建议的解决方案.agg({'set': lambda x: set(x)}),此问题仍然存在。

原因是set_aggregate中未能满足is_list_like这里提供了@EdChum的详细解释

因此,一个解决方案是将其强制转换为列表:

.agg({'set': lambda x: list(set(x))})


首先,.agg({'set': lambda x: list(set(x)})) 括号不匹配。但如果我修复为 .agg({'set': lambda x: list(set(x))}),我仍然会遇到 "SpecificationError: nested renamer is not supported"。 - InnocentBystander
这应该可以解决问题,.agg(lambda x: tuple(x.unique())) - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接