Pandas MultiIndex,选择1.和2.级别的值

时间:2018-03-25 15:14:43

标签: python pandas dataframe multi-index

通过选择1.和2.级别中的值来解决一些问题。

  

我通过设置header = [0,1]

获得了MultiIndex
In[1]:  df = pd.read_csv('Data.txt', sep='\t', header=[0,1], skipinitialspace=True)

In[2]:  print(df.columns)

Out[2]: MultiIndex(
        levels=[['20052065', '20052066', '20052082', '20052087', '20052089'], 
                ['CTF1', 'CTF2', 'CTF3', 'CTF_M', 'CTM1', 'CTM2', 'CTM3', 'CTM_M']],
        labels=[[...]],
        names=[...])
  

如果它试图获取2. level值和所选元素的数据   从1. level我得到以下输出:

In[3]:  print(df['20052065'][['CTF1','CTF_M']])

Out[3]: TIME[s]     CTF1    CTF_M
        0.000    -14.386   14.963
        60.000   -26.937   34.729
        120.000  -29.986   58.265
            ...      ...      ...
  

现在我尝试为2个元素生成输出并做了类似这样的事情:

In[4]:  print(df[['20052065','20052066']][['CTF1','CTF_M']])

Out[4]: KeyError: "['CTF1' 'CTF_M'] not in index"

不知怎的,这不起作用。也许你知道可怕的出了什么问题?

感谢您的帮助。

修改: In[1]: print(df)如下:

Out[1]:          ELEMENT 20052065 20052066 20052082 20052087 20052089 20052090  \
       TIME[s]   TEMP[C]     CTF1     CTF1     CTF1     CTF1     CTF1     CTF1   
       0.000      24.000   -4.234   -6.728  -14.386   -4.356   -6.926  -10.205   
       60.000     36.137  -29.308  -24.795  -26.937  -30.134  -24.735  -23.474 
          ...        ...      ...      ...      ...      ...      ...      ...

* .txt文件如下所示:

enter image description here

2 个答案:

答案 0 :(得分:2)

您可以使用df.loc

import numpy as np
import pandas as pd

columns = pd.MultiIndex.from_product([['A','B','C'],['X','Y','Z']])
df = pd.DataFrame(np.random.randint(10, size=(3,len(columns))), columns=columns)
#    A        B        C      
#    X  Y  Z  X  Y  Z  X  Y  Z
# 0  2  7  5  1  6  0  5  0  0
# 1  8  4  7  2  0  8  7  3  9
# 2  0  6  8  8  1  1  8  0  2

# In some cases `sort_index` may be needed to avoid UnsortedIndexError
df = df.sort_index(axis=1)
print(df.loc[:, (['A','B'],['X','Y'])])

收益率(类似):

   A     B   
   X  Y  X  Y
0  2  7  1  6
1  8  4  2  0
2  0  6  8  1

如果您只想选择('A','Y')('B','X')列,请注意您可以将MultiIndexed列指定为元组:

In [37]: df.loc[:, [('A','Y'),('B','X')]]
Out[37]: 
   A  B
   Y  X
0  7  1
1  4  2
2  6  8

甚至只是df[[('A','Y'),('B','X')]](产生相同的结果)。

通常最好使用单个索引器,例如df.loc[...]而不是双索引(例如df[...][...])。它可以更快(因为它减少了对__getitem__的调用,并生成了更少的临时子数据框)和df.loc[...] = value the correct way来分配DataFrame的子切片df本身。

df[['A','B']][['X','Y']]不起作用的原因是因为 df[['A','B']]返回带有MultiIndex的DataFrame:

In [36]: df[['A','B']]
Out[36]: 
   A        B      
   X  Y  Z  X  Y  Z
0  2  7  5  1  6  0
1  8  4  7  2  0  8
2  0  6  8  8  1  1

因此,使用['X','Y']为此DataFrame编制索引失败,因为没有名为'X''Y'的顶级列标签。

有时,根据DataFrame的构造方式(或由于在DataFrame上执行的操作),MultiIndex需要在被切片之前进行缩放。有boxed warning in the docs提到这个问题。要使用列索引lexsort,请使用

df = df.sort_index(axis=1)

答案 1 :(得分:1)

我认为需要slicers

print (df)
  20052065 20052066 20052065 20052066 20052065 20052066
      CTF1    CTF_M   CTF_M1   CTF_Mr        V        A
0        1        2        4        5        6        7

df = df.sort_index(axis=1)
idx = pd.IndexSlice
print (df.loc[:, idx[['20052065','20052066'], ['CTF1','CTF_M']]])
  20052065 20052066
      CTF1    CTF_M
0        1        2