熊猫:按熊猫0.23.4中的两列组合分组

时间:2018-12-03 08:29:17

标签: python python-3.x pandas

我对Python相当陌生。我遇到了Pandas: Group by combination of two columns。不幸的是,已接受的答案不再适用于熊猫版本0.23.4,该文章的目的是弄清楚组变量的组合,并为值创建字典。即group_by应该忽略分组的顺序。

这是公认的答案:

import pandas as pd
from collections import Counter

d = pd.DataFrame([('a','b',1), ('a','c', 2), ('b','a',3), ('b','a',3)],
                 columns=['x', 'y', 'score'])

d[['x', 'y']] = d[['x', 'y']].apply(sorted, axis=1)
x = d.groupby(['x', 'y']).agg(Counter)
print(x)

在这里,...apply(sorted)引发以下异常:

  

提高ValueError('必须具有相等的len键和值'ValueError:   设置可迭代项时必须具有相同的len键和值

这是我的熊猫版本:

> pd.__version__
Out: '0.23.4'

这是我在阅读https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.sort_values.html之后尝试过的方法:

d = pd.DataFrame([('a','b',1), ('a','c', 2), ('b','a',3), ('b','a',3)],
                 columns=['x', 'y', 'score'])

d=d.sort_values(by=['x','y'],axis=1).reset_index(drop=True)
x = d.groupby(['x', 'y']).agg(Counter)
print(x)

不幸的是,这也会引发错误:

  

1382,以_get_label_or_level_values       引发KeyError(key)KeyError:'x'

预期输出:

        score           count
x   y                     
a   b   {1: 1, 3: 2}      2
    c   {2: 1}            1 

有人可以帮我吗?附带说明一下,如果您还可以指导如何计算keys()列中score的计数,那就太好了。我正在寻找向量化的解决方案。

我正在使用python 3.6.7

非常感谢。

3 个答案:

答案 0 :(得分:2)

问题是sorted返回列表,所以有必要将ti转换为Series

d[['x', 'y']] = d[['x', 'y']].apply(lambda x: pd.Series(sorted(x)), axis=1)

但是将numpy.sortDataFrame构造函数一起使用会更快,因为apply是幕后的循环:

d = pd.DataFrame([('a','b',1), ('a','c', 2), ('b','a',3), ('b','a',3)],
                 columns=['x', 'y', 'score'])

d[['x', 'y']] = pd.DataFrame(np.sort(d[['x', 'y']], axis=1), index=d.index)

然后显示用于聚合的列,其中包含聚合函数的列表-例如nunique用于计算唯一值的数量:

x = d.groupby(['x', 'y'])['score'].agg([Counter, 'nunique'])
print(x)
          Counter  nunique
x y                       
a b  {1: 1, 3: 2}        2
  c        {2: 1}        1

或以DataFrameGroupBy.size计数:

x = d.groupby(['x', 'y'])['score'].agg([Counter, 'size'])
print(x)
          Counter  size
x y                    
a b  {1: 1, 3: 2}     3
  c        {2: 1}     1

答案 1 :(得分:1)

使用-

a=d[['x','y']].values
a.sort(axis=1)
d[['x','y']] = a
x = d.groupby(['x', 'y']).agg(Counter)
print(x)

输出

            score
x y              
a b  {1: 1, 3: 2}
  c        {2: 1}

答案 2 :(得分:1)

result_type = 'broadcast'添加为.apply()的参数之一是可行的。

>>> d = pd.DataFrame([('a','b',1), ('a','c', 2), ('b','a',3), ('b','a',3)],
             columns=['x', 'y', 'score'])
>>> d[['x', 'y']] = d[['x', 'y']].apply(sorted, axis=1, result_type='broadcast')
>>> x = d.groupby(['x', 'y']).agg(Counter)
>>> print(x)

            score
x y              
a b  {1: 1, 3: 2}
  c        {2: 1}

请注意带和不带result_type = 'broadcast'的区别。

>>> d[['x', 'y']].apply(sorted, axis=1)

0    [a, b]
1    [a, c]
2    [a, b]
3    [a, b]
dtype: object

>>> d[['x', 'y']].apply(sorted, axis=1, result_type='broadcast')

   x  y
0  a  b
1  a  c
2  a  b
3  a  b

如您所见,result_type = 'broadcast'.apply()的结果从列表中拆分(广播)到相应的列中,从而可以分配给d[['x', 'y']]

相关问题