将熊猫数据框分组并将多个值收集到集合中
Posted
技术标签:
【中文标题】将熊猫数据框分组并将多个值收集到集合中【英文标题】:Grouping pandas dataframe and collecting multiple values into sets 【发布时间】:2017-11-01 12:00:31 【问题描述】:假设我有以下数据框df1
:
A B C D
0 foo one 1 0
1 bar two 2 1
2 foo two 3 0
3 bar two 4 1
4 foo two 5 0
5 bar two 6 1
6 foo one 7 0
7 foo two 8 1
我想把它变成一个数据框df2
,像这样:
A B C D
foo [one,two] [1,3,5,7,8] 0
bar [two] [2,4,6] 1
更准确地说:
按A
分组,即A
列是索引,每行A
的值都是唯一的
B
和 C
列包含出现的值的聚合集。对于A = "foo"
,B
是"one"
或"two"
,而对于"bar"
,它只是"two"
。
set
,但我也想知道用 pandas 来表示它的最优雅的方式是什么
列 D
不包含集合,因为对于 foo
,D
始终为 0,而对于 bar
,它始终为 1。如果索引值和列值,则该列不应包含集合。
我预计会有一个像 df1.groupby("A").aggregate_like_this()
这样的单行聚合,但到目前为止我没有找到它。
【问题讨论】:
【参考方案1】:使用groupby
+ agg
:
f = 'B' : lambda x: np.unique(x).tolist(),
'C' : lambda x: np.unique(x).tolist(),
'D' : 'first'
df.groupby('A', as_index=False).agg(f).reindex(columns=df.columns)
A B C D
0 bar [two] [2, 4, 6] 1
1 foo [one, two] [1, 3, 5, 7, 8] 0
如果您无法提前确定 A
的哪些值与 D
具有 1:1 的关系,请使用 groupby
+ nunique
进行检查,然后相应地过滤您的数据集。
x = df.groupby('A').D.nunique().eq(1)
df = df[df.A.isin(x[x].index)]
df
A B C D
1 bar two 2 1
3 bar two 4 1
5 bar two 6 1
df.groupby('A', as_index=False).agg(f).reindex(columns=df.columns)
A B C D
0 bar [two] [2, 4, 6] 1
【讨论】:
这里我需要事先知道D列与索引值有这种1:1的关系。这意味着我需要为每一列手动测试。有没有办法让 pandas 自动执行此操作? 你写'D': 'first'
,告诉pandas为列D
取第一个值,因为我告诉过你列D
有这个属性,只有一个D
的值A
的每个值。但如果我们不知道这一点呢?
@clstaudt 无论我们是否知道 D 和 A 的关系,它都会盲目地取第一个值。如果没有唯一值,你想做什么?
@Wen 这是一个选项,但我认为np.unique
在大型数组上比set
快...而且D
不能成为列表列。
基于他的样本数据,即设置在一组中包含 [0,1] .. :-)以上是关于将熊猫数据框分组并将多个值收集到集合中的主要内容,如果未能解决你的问题,请参考以下文章