来自 groupby 多列的 bin 大小的嵌套字典
Posted
技术标签:
【中文标题】来自 groupby 多列的 bin 大小的嵌套字典【英文标题】:nested dictionary of bin sizes from groupby multiple columns 【发布时间】:2018-09-30 04:20:14 【问题描述】:df = pd.DataFrame('a': [1,1,1,1,2,2,2,2,3,3,3,3], 'b': [5,5,1,1,3,3,3,1,2,1,1,1,])
>>> df
a b
0 1 5
1 1 5
2 1 1
3 1 1
4 2 3
5 2 3
6 2 3
7 2 1
8 3 2
9 3 1
10 3 1
11 3 1
>>> df.groupby(['a','b']).size().to_dict()
(1, 5): 2, (3, 2): 1, (2, 3): 3, (3, 1): 3, (1, 1): 2, (2, 1): 1
我得到的是每个 a
和 b
组合的计数以及一对 tuple
作为 key
但我想要得到的是:
1: 5: 2, 1: 2, 2: 3: 3, 1: 1, 3: 2: 1, 1: 3
【问题讨论】:
【参考方案1】:你需要一个额外的groupby
在字典理解中:
i = df.groupby(['a','b']).size().reset_index(level=1)
j = k : dict(g.values) for k, g in i.groupby(level=0)
print(j)
1: 1: 2, 5: 2,
2: 1: 1, 3: 3,
3: 1: 3, 2: 1
【讨论】:
【参考方案2】:您可以使用collections.defaultdict
获得 O(n) 解决方案。
from collections import defaultdict
df = pd.DataFrame('a': [1,1,1,1,2,2,2,2,3,3,3,3], 'b': [5,5,1,1,3,3,3,1,2,1,1,1,])**Option 2: defaultdict**
d = defaultdict(lambda: defaultdict(int))
for i, j in map(tuple, df.values):
d[i][j] += 1
# defaultdict(<function __main__.<lambda>>,
# 1: defaultdict(int, 1: 2, 5: 2),
# 2: defaultdict(int, 1: 1, 3: 3),
# 3: defaultdict(int, 1: 3, 2: 1))
【讨论】:
感谢您的回答。这就是我目前使用的方法。我只是想知道 pandas 工具是否提供了一种矢量化的方法来实现这一目标 我的解决方案是 not 矢量化的,它是一个纯 Python 循环。 @Tony 作为一般规则,不要假设groupby
或apply
意味着vectorized
...它没有。 jpp 强调 O(n) 解决方案是正确的。但是,cᴏʟᴅsᴘᴇᴇᴅ 也提供了 O(n) 解决方案。如果性能是一个问题,请务必在您的问题中说明。它会告诉我们如何回答。 jpp 再次正确地建议您应该对您的数据进行测试。假设一个简单的 for 循环总是更糟是错误的。
@piRSquared 我没有在我的问题中提到它,因为在我看来,最简单的解决方案将涉及类似于以下内容:link,我只是无法弄清楚自己。你是对的,我应该在我的要求中更加明确。感谢您的回答
我会继续说明我喜欢这种方法的原因。循环所涉及的大部分开销(即使在 O(n) 时)是对象的创建。在我的解决方案和 cᴏʟᴅsᴘᴇᴇᴅ's 中,我们在理解范围内创建 Pandas 对象。 jpp 的解决方案避免了这种开销,并简单地添加到现有密钥中。这应该是有效的【参考方案3】:
from collections import Counter
import pandas as pd
s = pd.Series(Counter(zip(df.a, df.b)))
n: d.xs(n).to_dict()
for n, d in s.groupby(level=0)
1: 1: 2, 5: 2, 2: 1: 1, 3: 3, 3: 1: 3, 2: 1
【讨论】:
以上是关于来自 groupby 多列的 bin 大小的嵌套字典的主要内容,如果未能解决你的问题,请参考以下文章
为啥在 col-auto 内具有多列的嵌套行的大小大于内容宽度?