Python groupby多列的箱大小嵌套字典

Python groupby多列的箱大小嵌套字典,python,pandas,dictionary,dataframe,pandas-groupby,Python,Pandas,Dictionary,Dataframe,Pandas Groupby,我得到的是每一个a和b组合的计数,以及作为键的元组的计数,但我试图得到的是: 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

我得到的是每一个
a
b
组合的计数,以及作为
键的
元组的
计数,但我试图得到的是:

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}

您需要在dict理解中添加一个
groupby

{1: {5: 2, 1: 2}, 2: {3: 3, 1: 1}, 3: {2: 1, 1: 3} }


对于O(n)解决方案,可以使用
collections.defaultdict

print(j)
{
    1: {1: 2, 5: 2}, 
    2: {1: 1, 3: 3}, 
    3: {1: 3, 2: 1}
}
从集合导入defaultdict
df=pd.数据帧({'a':[1,1,1,2,2,2,2,3,3,3],'b':[5,5,1,1,3,3,3,1,2,1,1,1,]})**选项2:defaultdict**
d=defaultdict(lambda:defaultdict(int))
对于映射中的i,j(元组,df.值):
d[i][j]+=1
#defaultdict(,
#{1:defaultdict(int,{1:2,5:2}),
#2:defaultdict(int,{1:1,3:3}),
#3:defaultdict(int,{1:3,2:1})

谢谢您的回答。这就是我目前使用的方法。我只是想知道pandas工具是否提供了实现这一点的矢量化方法。我的解决方案不是矢量化的,它是一个纯Python循环。@Tony作为一般规则,不要假设
groupby
apply
意味着
矢量化的
。。。没有。jpp强调O(n)解决方案是正确的。然而,cᴏʟᴅsᴘᴇᴇᴅ 也提供了一个O(n)解决方案。如果性能是一个问题,请确保在问题中这样说。它将告诉我们如何回答。jpp再次正确地建议您应该在您的数据上测试这一点。假设一个简单的for循环总是更糟糕是错误的。@piRSquared我在我的问题中没有提到它,因为在我看来,最简单的解决方案会涉及到类似的东西:我只是无法理解自己。你说得对,我的要求应该更明确一些。谢谢你的回答。我会继续解释为什么我喜欢这种方法。循环(即使是O(n))所涉及的大部分开销都是对象的创建。在我的解决方案和cᴏʟᴅsᴘᴇᴇᴅ's、 我们正在一个理解范围内创建对象。jpp的解决方案避免了这种开销,只需添加到现有密钥中。这应该是有效的
print(j)
{
    1: {1: 2, 5: 2}, 
    2: {1: 1, 3: 3}, 
    3: {1: 3, 2: 1}
}
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})})
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}}