pandas xs和loc之间的重复索引不一致

时间:2017-09-07 13:48:23

标签: python pandas indexing multi-index

为什么.loc只返回多行具有相同MultiIndex的单行?

给出以下数据框

           col0      col1  col2
idx0 idx1
0    0      1.0  example1   1.0
     0      4.0  example2   8.0
     1      9.0  example3  27.0
     1     16.0  example4  64.0
1    0      0.5  example1   0.5
     0      2.0  example2   4.0
     1      4.5  example3  13.5
     1      8.0  example4  32.0

.xs操作将选择

In [121]: df.xs((0,1), level=[0,1])
Out[121]:
           col0      col1  col2
idx0 idx1
0    1      9.0  example3  27.0
     1     16.0  example4  64.0

.loc操作将选择

In [125]: df.loc[[(0,1)]]
Out[125]:
           col0      col1  col2
idx0 idx1
0    1     16.0  example4  64.0

以下

进一步强调了这一点
In [149]: df.loc[pd.IndexSlice[:, 1], :]
Out[149]:
           col0      col1  col2
idx0 idx1
0    1      9.0  example3  27.0
     1     16.0  example4  64.0

In [150]: df.loc[pd.IndexSlice[0, 1], :]
Out[150]:
col0          16
col1    example4
col2          64
Name: (0, 1), dtype: object

设置

import pandas as pd
import numpy as np
idx0 = range(2)
idx1 = np.repeat(range(2), 2)

midx = pd.MultiIndex(
    levels=[idx0, idx1],
    labels=[
        np.repeat(range(len(idx0)), len(idx1)),
        np.tile(range(len(idx1)), len(idx0))
    ],
    names=['idx0', 'idx1']
)

df = pd.DataFrame(
    [
        [i**2/float(j), 'example{}'.format(i), i**3/float(j)]
        for j in range(1, len(idx0) + 1)
        for i in range(1, len(idx1) + 1)
    ],
    columns=['col0', 'col1', 'col2'],
    index=midx
)

2 个答案:

答案 0 :(得分:1)

使用.xs

df.xs((0,1), level=[0,1])
Out[74]: 
           col0      col1  col2
idx0 idx1                      
0    1      9.0  example3  27.0
     1     16.0  example4  64.0

使用.loc

df.loc[0].loc[1]
Out[75]: 
      col0      col1  col2
idx1                      
1      9.0  example3  27.0
1     16.0  example4  64.0

在辅助索引中添加[] :( PS:link

df.loc[(0, [1]),:]

Out[90]: 
           col0      col1  col2
idx0 idx1                      
0    1      9.0  example3  27.0
     1     16.0  example4  64.0

答案 1 :(得分:1)

我不相信您的多索引已正确创建。

df = df.assign(
    idx0=[0] * 4 + [1] * 4, 
    idx1=[0, 0, 1, 1] * 2).set_index(['idx0', 'idx1'])

使用正确的方法之一loc来访问数据:

>>> df.loc[(0, 1), :]
           col0      col1  col2
idx0 idx1                      
0    1        9  example3    27
     1       16  example4    64

在原始数据帧上使用相同的命令,我得到: TypeError: only integer arrays with one element can be converted to an index

<强>更新

正如我之前提到的,您似乎没有正确创建多索引。具有正确构造的多索引的数据框与您的示例一起工作(使用较旧的pandas,v 0.17.2)。

midx = pd.MultiIndex.from_product([[0, 1], [0, 0, 1, 1]], names=['idx0', 'idx1'])
df = pd.DataFrame(
    [
        [i**2/float(j), 'example{}'.format(i), i**3/float(j)]
        for j in range(1, len(idx0) + 1)
        for i in range(1, len(idx1) + 1)
    ],
    columns=['col0', 'col1', 'col2'],
    index=midx)

使用上面定义的midx

>>> midx
MultiIndex(levels=[[0, 1], [0, 1]],
           labels=[[0, 0, 0, 0, 1, 1, 1, 1], [0, 0, 1, 1, 0, 0, 1, 1]],
           names=[u'idx0', u'idx1'])

根据您的定义使用midx

>>> midx
MultiIndex(levels=[[0, 1], [0, 0, 1, 1]],
           labels=[[0, 0, 0, 0, 1, 1, 1, 1], [0, 1, 2, 3, 0, 1, 2, 3]],
           names=[u'idx0', u'idx1'])