熊猫在第一层上唯一时的byby multiindex:意外结果

时间:2018-11-19 20:20:57

标签: python pandas pandas-groupby

Python版本:3.5.2;熊猫版:0.23.1

当我使用两个索引进行分组时,我注意到了意外的行为,但是第一行的每一行都是唯一的。我正在数据列第c列上执行的代码是:

df.c.groupby(df.index.names).min()

当行在第一个索引上不是唯一时,一切都会按预期进行。为了清楚起见,我在下面提供了两个版本。编辑:现在包括三个版本!

版本1:具有预期的输出

df = pd.DataFrame([[1, 2, 3], [4, 5, 6], [1, 2, 4]], columns=['a', 'b', 'c'])
df = df.set_index(['a','b']).sort_index()

输入:

     c
a b   
1 2  3
  2  4
4 5  6

输出:

a  b
1  2    3
4  5    6

版本2:具有意外的输出

df = pd.DataFrame([[1, 2, 3], [4, 5, 6]], columns=['a', 'b', 'c'])
df = df.set_index(['a','b']).sort_index()

输入:

     c
a b   
1 2  3
4 5  6

输出:

a    3
b    6

预期输出:

a  b
1  2    3
4  5    6

版本3:具有预期的输出,但考虑到版本2则没有预期。

df = pd.DataFrame([[1, 2, 3, 4], [4, 5, 6, 7]], columns=['a', 'b1', 'b2', 'c'])
df = df.set_index(['a','b1','b2']).sort_index()

输入:

         c
a b1 b2   
1 2  3   4
4 5  6   7

输出:

a  b1  b2
1  2   3     4
4  5   6     7

3 个答案:

答案 0 :(得分:1)

这是正在发生的事情。看一下传递给“应用的”函数f的系列的名称。

在第一种情况下(预期结果):

df = pd.DataFrame([[1, 2, 3], [4, 5, 6], [1, 2, 4]], columns=['a', 'b', 'c'])
df = df.set_index(['a','b']).sort_index()

def f(x):
    print(x)
    print('\n')
    print(min(x))
    print('\n')
    return min(x)
df.c.groupby(['a','b']).apply(f)

输出:

a  b
1  2    3
   2    4
Name: (1, 2), dtype: int64


3


a  b
4  5    6
Name: (4, 5), dtype: int64


6


Out[292]:

a  b
1  2    3
4  5    6

在第二种情况下(意外结果),记下传入的系列的名称:

df1 = pd.DataFrame([[1, 2, 3], [4, 5, 6]], columns=['a', 'b', 'c'])
df1 = df1.set_index(['a','b']).sort_index()
def f(x):
    print(x)
    print('\n')
    print(min(x))
    print('\n')
    return min(x)
df1.c.groupby(['a','b']).apply(f)

输出:

a  b
1  2    3
Name: a, dtype: int64


3


a  b
4  5    6
Name: b, dtype: int64


6


Out[293]:

a    3
b    6
Name: c, dtype: int64

它使用这些系列来构建结果数据框。由于数据的性质,该系列的命名是罪魁祸首。为什么?好吧,我们必须研究一下代码。

此问题的惯用解决方法是使用以下语法:

df1.groupby(df1.index.names)['c'].min()

输出:

a  b
1  2    3
4  5    6
Name: c, dtype: int64

答案 1 :(得分:0)

您可以使用groupby的level参数:

>>> df
     c
a b   
1 2  3
4 5  6

>>> df.c.groupby(level=[0,1]).min()
a  b
1  2    3
4  5    6
Name: c, dtype: int64

docs

  

级别:整数,级别名称或此类的序列,默认为无

     
    

如果轴是MultiIndex(分层),则按一个或多个特定级别分组

  

答案 2 :(得分:0)

现在,这种行为已在熊猫中更改。现在,在所有情况下输出都将与预期输出匹配。