【问题标题】:pandas loc modifies dataFrame with multi index?pandas loc用多索引修改dataFrame?
【发布时间】:2017-03-11 03:32:19
【问题描述】:

我发现了一些有趣的 loc 行为(错误?),具有多索引数据框,其中第一个索引是单一的。使用 loc (第一次)后,第一个索引(多索引)消失了!

示例:

In [1]: import pandas as pd

In [2]: x = pd.DataFrame({'idx1':[1]*10, 'idx2':[1]*5+[2]*5, 'idx3':range(5)+range(5), 'data': [1]*10})

In [3]: x = x.set_index(['idx1', 'idx2', 'idx3']).sortlevel()

我的数据框:

In [4]: x
Out[4]:
                data
idx1 idx2 idx3
1    1    0        1
          1        1
          2        1
          3        1
          4        1
     2    0        1
          1        1
          2        1
          3        1
          4        1

第一次使用的位置:

In [5]: x.loc[1,:,:]
Out[5]:
           data
idx2 idx3
1    0        1
     1        1
     2        1
     3        1
     4        1
2    0        1
     1        1
     2        1
     3        1
     4        1

现在DataFrame只有两个索引:

In [6]: x
Out[6]:
           data
idx2 idx3
1    0        1
     1        1
     2        1
     3        1
     4        1
2    0        1
     1        1
     2        1
     3        1
     4        1

当 'idx1' 有多个值时,不会发生这种情况:

In [7]: x = pd.DataFrame({'idx1':[1]*3+[2]*7, 'idx2':[1]*5+[2]*5, 'idx3':range(5)+range(5), 'data': [1]*10})

In [8]: x = x.set_index(['idx1', 'idx2', 'idx3']).sortlevel()

In [9]: x
Out[9]:
                data
idx1 idx2 idx3
1    1    0        1
          1        1
          2        1
2    1    3        1
          4        1
     2    0        1
          1        1
          2        1
          3        1
          4        1

In [10]: x.loc[1,:,:]
Out[10]:
                data
idx1 idx2 idx3
1    1    0        1
          1        1
          2        1

In [11]: x
Out[11]:
                data
idx1 idx2 idx3
1    1    0        1
          1        1
          2        1
2    1    3        1
          4        1
     2    0        1
          1        1
          2        1
          3        1
          4        1

这是正常行为吗?如何避免这种情况?

python 2.7 32bit,pandas==0.16.2,numpy==1.11.1+mkl

【问题讨论】:

    标签: python pandas indexing multi-index


    【解决方案1】:

    我认为用slicers 选择更好,然后它返回相同的输出 - 所有级别:

    x = pd.DataFrame({'idx1':[1]*10, 'idx2':[1]*5+[2]*5, 'idx3':list(range(5))+list(range(5)), 'data': [1]*10})
    x = x.set_index(['idx1', 'idx2', 'idx3']).sortlevel()
    print (x)
                    data
    idx1 idx2 idx3      
    1    1    0        1
              1        1
              2        1
              3        1
              4        1
         2    0        1
              1        1
              2        1
              3        1
              4        1
    
    idx = pd.IndexSlice
    print (x.loc[idx[1,:,:],:])
                    data
    idx1 idx2 idx3      
    1    1    0        1
              1        1
              2        1
              3        1
              4        1
         2    0        1
              1        1
              2        1
              3        1
              4        1
    

    如果需要删除级别,使用xs和参数drop_level

    print (x.xs(1, level=0, drop_level=True))
               data
    idx2 idx3      
    1    0        1
         1        1
         2        1
         3        1
         4        1
    2    0        1
         1        1
         2        1
         3        1
         4        1
    
    print (x.xs(1, level=0, drop_level=False))
                    data
    idx1 idx2 idx3      
    1    1    0        1
              1        1
              2        1
              3        1
              4        1
         2    0        1
              1        1
              2        1
              3        1
              4        1
    

    第二个样本:

    x = pd.DataFrame({'idx1':[1]*3+[2]*7, 'idx2':[1]*5+[2]*5, 'idx3':list(range(5))+list(range(5)), 'data': [1]*10})
    
    x = x.set_index(['idx1', 'idx2', 'idx3']).sortlevel()
    print (x)
                    data
    idx1 idx2 idx3      
    1    1    0        1
              1        1
              2        1
    2    1    3        1
              4        1
         2    0        1
              1        1
              2        1
              3        1
              4        1
    
    idx = pd.IndexSlice
    print (x.loc[idx[1,:,:],:])
                    data
    idx1 idx2 idx3      
    1    1    0        1
              1        1
              2        1
    
    print (x.xs(1, level=0, drop_level=True))
               data
    idx2 idx3      
    1    0        1
         1        1
         2        1
    
    print (x.xs(1, level=0, drop_level=False))
                    data
    idx1 idx2 idx3      
    1    1    0        1
              1        1
              2        1
    

    【讨论】:

      猜你喜欢
      • 2015-02-14
      • 1970-01-01
      • 2018-01-18
      • 2019-04-13
      • 2021-10-30
      • 2021-12-08
      • 1970-01-01
      • 2022-01-10
      • 2019-04-17
      相关资源
      最近更新 更多