熊猫:multiIndex数据框上的部分索引不重复行

时间:2020-05-18 13:17:55

标签: python pandas multi-index

我正在尝试使用.loc索引和标签列表从两级熊猫MultiIndex数据框中选择行(包括重复)。

但是,如果我尝试使用MultiIndex数据帧进行这种类型的索引编制,则输出的行顺序与输入的顺序相同,并且重复的索引将被忽略。这是一个示例:

import numpy as np
import pandas as pd
import string as s

index1 = list(s.ascii_uppercase[:4])
index2 = np.arange(2)
col_names='col1 col2 col3'.split()

new_slices = list('DDAB') # note order and repition of labels

multi_index = pd.MultiIndex.from_product([index1,index2],names=["level0","level1"])

data = np.arange(len(index1)*len(index2)*len(col_names))
data=data.reshape(len(index1)*len(index2),-1)


df2 = pd.DataFrame(data,columns=col_names,index=multi_index)

print(df2.loc[new_slices])

               col1  col2  col3
level0 level1                  
A      0          0     1     2
       1          3     4     5
B      0          6     7     8
       1          9    10    11
D      0         18    19    20
       1         21    22    23

我会期望:

               col1  col2  col3
level0 level1                  
D      0         18    19    20
       1         21    22    23
D      0         18    19    20
       1         21    22    23
A      0          0     1     2
       1          3     4     5
B      0          6     7     8
       1          9    10    11

我是否错过了特定于MultiIndex的功能? 还是我误解了MultiIndex中的级别如何工作?

(但是,这在我从“常规”数据帧中进行选择时可以达到预期效果,例如:)

import numpy as np
import pandas as pd
import string as s

index1 = list(s.ascii_uppercase[:4])
col_names='col1 col2 col3'.split()

new_slices = list('DDAB') # note order and repition of labels

data1 = np.arange(len(index1)*len(col_names)).reshape(len(index1),-1)
df1 = pd.DataFrame(data1,columns=col_names,index=index1)

print(df1)
print(df1.loc[new_slices])

给出我期望的结果-具有D,D,A,B行的数据框。

2 个答案:

答案 0 :(得分:2)

以这种方式尝试

index1 = list(s.ascii_uppercase[:4])
index2 = np.arange(2)
col_names='col1 col2 col3'.split()

new_slices = list('DDAB') # note order and repition of labels

multi_index = pd.MultiIndex.from_product([index1,index2],names=["level0","level1"])

data = np.arange(len(index1)*len(index2)*len(col_names))
data=data.reshape(len(index1)*len(index2),-1)


df2 = pd.DataFrame(data,columns=col_names,index=multi_index)
df2.unstack().loc[new_slices].stack() # <=== this does the trick

enter image description here

答案 1 :(得分:2)

您什么都没错过。这是熊猫实现索引的方式的结果。部分索引不会重复行,而只会完全索引。

部分:只有第一级的两个:

df2.loc[['A', 'A']]

               col1  col2  col3
level0 level1                  
A      0          0     1     2
       1          3     4     5

部分:只有第二个级别中的两个:

df2.loc[(slice(None), [0, 0]), :]

               col1  col2  col3
level0 level1                  
A      0          0     1     2
B      0          6     7     8
C      0         12    13    14
D      0         18    19    20

但是,完整索引不会重复行:

df2.loc[[('A', 0),('A', 0)]]

               col1  col2  col3
level0 level1                  
A      0          0     1     2
       0          0     1     2

这是特定情况的一般情况,即在单个索引上建立索引会复制行。单个索引上的所有索引都已完成,因为只有一个级别。

如果您想通过索引而不是通过缩进或联接来获取重复的行,则可以构建一个完整的索引列表,如下所示:

complete = [(first, second) for first in new_slices for second in set(df2.index.get_level_values(1))]
df2.loc[complete]

               col1  col2  col3
level0 level1                  
D      0         18    19    20
       1         21    22    23
       0         18    19    20
       1         21    22    23
A      0          0     1     2
       1          3     4     5
B      0          6     7     8
       1          9    10    11