合并两个Pandas索引切片。

3

如何将两个pandas.IndexSlice组合成一个?

问题的设定:

import pandas as pd
import numpy as np

idx = pd.IndexSlice
cols = pd.MultiIndex.from_product([['A', 'B', 'C'], ['x', 'y'], ['a', 'b']])
df = pd.DataFrame(np.arange(len(cols)*2).reshape((2, len(cols))), columns=cols)

df:
    A               B               C            
    x       y       x       y       x       y    
    a   b   a   b   a   b   a   b   a   b   a   b
0   0   1   2   3   4   5   6   7   8   9  10  11
1  12  13  14  15  16  17  18  19  20  21  22  23

如何将两个切片idx['A', 'y', :]idx[['B', 'C'], 'x', :]合并为一个数据框呢?

分别是:

df.loc[:, idx['A', 'y',:]]
    A    
    y    
    a   b
0   2   3
1  14  15


df.loc[:, idx[['B', 'C'], 'x', :]]
    B       C    
    x       x    
    a   b   a   b
0   4   5   8   9
1  16  17  20  21

仅仅将它们组合成一个列表并不完美:

df.loc[:, [idx['A', 'y',:], idx[['B', 'C'], 'x',:]]]
....
TypeError: unhashable type: 'slice'

我目前的解决方案非常繁琐,但是可以提供我所需的子df:

df.loc[:, df.loc[:, idx['A', 'y', :]].columns.to_list() + df.loc[:,
       idx[['B', 'C'], 'x', :]].columns.to_list()]
    A       B       C    
    y       x       x    
    a   b   a   b   a   b
0   2   3   4   5   8   9
1  14  15  16  17  20  21

然而,当切片中只有一个系列(如预期),这种方法就不起作用了,这就没那么有趣了:
df.loc[:, df.loc[:, idx['A', 'y', 'a']].columns.to_list() + df.loc[:,
       idx[['B', 'C'], 'x', :]].columns.to_list()]
...
AttributeError: 'Series' object has no attribute 'columns'

有没有更好的替代方案,最好能与数据帧切片和序列切片一起使用?

2个回答

4
通用解决方法是将两个切片合并在一起:
a = df.loc[:, idx['A', 'y', 'a']]
b = df.loc[:, idx[['B', 'C'], 'x', :]]

df = pd.concat([a, b], axis=1)
print (df)
    A   B       C    
    y   x       x    
    a   a   b   a   b
0   2   4   5   8   9
1  14  16  17  20  21

1
一个选项是使用pyjanitor select_columns 来通过元组进行选择:
# pip install pyjanitor
import pandas as pd

df.select_columns(('A','y'), ('B','x'), ('C','x'))
    A       B       C    
    y       x       x    
    a   b   a   b   a   b
0   2   3   4   5   8   9
1  14  15  16  17  20  21

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接