Pandas:在列表的每个元素上使用 groupby
Posted
技术标签:
【中文标题】Pandas:在列表的每个元素上使用 groupby【英文标题】:Pandas : Use groupby on each element of list 【发布时间】:2017-06-06 10:05:55 【问题描述】:也许我错过了显而易见的事情。
我有一个看起来像这样的熊猫数据框:
id product categories
0 Silmarillion ['Book', 'Fantasy']
1 Headphones ['Electronic', 'Material']
2 Dune ['Book', 'Sci-Fi']
我想使用 groupby 函数来统计类别列中每个元素的出现次数,所以这里的结果是
Book 2
Fantasy 1
Electronic 1
Material 1
Sci-Fi 1
但是,当我尝试使用 groupby 函数时,pandas 会计算整个列表的出现次数,而不是分离其元素。我尝试了多种不同的方法来处理这个问题,使用元组或拆分,但到目前为止我还没有成功。
【问题讨论】:
旁白:pandas 目前还不完全支持非标量条目,使用它们时有时会出现神秘的故障。修改框架通常更安全,这样每一行都只包含标量条目。 【参考方案1】:您也可以直接在列表中调用pd.value_counts
。
您可以通过numpy.concatenate
、itertools.chain
或cytoolz.concat
生成相应的列表
from cytoolz import concat
from itertools import chain
cytoolz.concat
pd.value_counts(list(concat(df.categories.values.tolist())))
itertools.chain
pd.value_counts(list(chain(*df.categories.values.tolist())))
numpy.unique
+ numpy.concatenate
u, c = np.unique(np.concatenate(df.categories.values), return_counts=True)
pd.Series(c, u)
全部收益
Book 2
Electronic 1
Fantasy 1
Material 1
Sci-Fi 1
dtype: int64
时间测试
【讨论】:
谢谢@NickilMaveli...我错过了 ;-) 我感到困惑 ;-)【参考方案2】:您可以通过堆叠记录来规范化记录,然后调用value_counts()
:
pd.DataFrame(df['categories'].tolist()).stack().value_counts()
Out:
Book 2
Fantasy 1
Material 1
Sci-Fi 1
Electronic 1
dtype: int64
【讨论】:
【参考方案3】:试试这个:
In [58]: df['categories'].apply(pd.Series).stack().value_counts()
Out[58]:
Book 2
Fantasy 1
Electronic 1
Sci-Fi 1
Material 1
dtype: int64
【讨论】:
@ayhan,你为什么要删除你的解决方案?我想它比我的好 @MaxU.apply(pd.Series)
似乎比 pd.DataFrame(ser.tolist())
更明确。我的看起来像一个副作用,将来可能不会起作用。
@ayhan,但与df['categories'].apply(pd.Series)
相比,pd.DataFrame(df['categories'].tolist())
很可能会更快。无论如何,为了完整起见(并有选择),我会要求你取消删除你的答案;-)
我都试过了。它们都可以工作,但“tolist()”变体似乎要快得多
@Skum,是的,我也比我更喜欢 ayhan 的解决方案! :-)以上是关于Pandas:在列表的每个元素上使用 groupby的主要内容,如果未能解决你的问题,请参考以下文章
如果 pandas 系列的值是一个列表,如何获取每个元素的子列表?
Pandas列表的列,通过迭代(选择)三列的每个列表元素作为新列和行来创建多列[重复]
在每个元素都是列表的数据帧中运行 Scipy Linregress