筛选具有两级列标题的panda数据帧



我正在尝试过滤一个pandas数据帧,该数据帧具有两级列标题,使用isin的标准方式使用列表,并使用掩码来重新运行新的过滤数据帧。然而,我在重叠的索引名称周围不断遇到一个值错误,我似乎无法解决。

以下是我想要筛选的列表的示例,以及数据帧本身。不确定如何提供生成此数据帧所需的代码,因为它是从csv文件导入的。

my_list = ['DEF', 'GHI']
+------+--------+----------+---+----------+---+
| CODE |  NAME  | STANDARD |   | ADVANCED |   |
+------+--------+----------+---+----------+---+
| CODE | NAME   | A        | B | A        | B |
+------+--------+----------+---+----------+---+
| ABC  | APPLE  | 1        | 1 | 2        | 2 |
| DEF  | BANANA | 3        | 3 | 4        | 4 |
| GHI  | KIWI   | 5        | 5 | 6        | 6 |
| JKL  | MANGO  | 7        | 7 | 8        | 8 |
+------+--------+----------+---+----------+---+

运行以下线路过滤

new_df = df[df['CODE'].isin(my_list)]

返回

ValueError: cannot join with no overlapping index names

然而,如果我自己运行df['CODE'].isin(my_list),这似乎有效,并返回具有True/False值的Symbol列,这意味着在将掩码应用于原始数据帧时出现了问题。

df源代码

[{('CODE', 'CODE'): 'ABC',
('NAME', 'NAME'): 'APPLE',
('STANDARD', 'A'): 1,
('STANDARD', 'B'): 1,
('ADVANCED', 'A'): 2,
('ADVANCED', 'B'): 2},
{('CODE', 'CODE'): 'DEF',
('NAME', 'NAME'): 'BANANA',
('STANDARD', 'A'): 3,
('STANDARD', 'B'): 3,
('ADVANCED', 'A'): 4,
('ADVANCED', 'B'): 4},
{('CODE', 'CODE'): 'GHI',
('NAME', 'NAME'): 'KIWI',
('STANDARD', 'A'): 5,
('STANDARD', 'B'): 5,
('ADVANCED', 'A'): 6,
('ADVANCED', 'B'): 6},
{('CODE', 'CODE'): 'JKL',
('NAME', 'NAME'): 'MANGO',
('STANDARD', 'A'): 7,
('STANDARD', 'B'): 7,
('ADVANCED', 'A'): 8,
('ADVANCED', 'B'): 8}]

看看df['CODE'].isin(my_list)产生了什么:

CODE
0  False
1   True
2   True
3  False

与单一级别指数相比:

my_list = ['DEF', 'GHI']
df = pd.DataFrame({
'CODE': ['ABC', 'DEF', 'GHI', 'JKL']
})
print(df['CODE'].isin(my_list))
0    False
1     True
2     True
3    False
Name: CODE, dtype: bool

修复

要么从CODE:中获取索引

new_df = df[df['CODE'].isin(my_list)['CODE']]

或者直接引用MultiIndex:

new_df = df[df[('CODE', 'CODE')].isin(my_list)]

两者都生产:

new_df:

CODE    NAME STANDARD    ADVANCED   
CODE    NAME        A  B        A  B
1  DEF  BANANA        3  3        4  4
2  GHI    KIWI        5  5        6  6

完整工作示例:

import pandas as pd
my_list = ['DEF', 'GHI']
df = pd.DataFrame({
('CODE', 'CODE'): ['ABC', 'DEF', 'GHI', 'JKL'],
('NAME', 'NAME'): ['APPLE', 'BANANA', 'KIWI', 'MANGO'],
('STANDARD', 'A'): [1, 3, 5, 7], ('STANDARD', 'B'): [1, 3, 5, 7],
('ADVANCED', 'A'): [2, 4, 6, 8], ('ADVANCED', 'B'): [2, 4, 6, 8]
})
new_df = df[df[('CODE', 'CODE')].isin(my_list)]
print(new_df)

当有多个index时,我通常用位置切片

my_list = ['DEF', 'GHI']
df.iloc[:,0].isin(my_list)
Out[49]: 
0    False
1     True
2     True
3    False
Name: (CODE, CODE), dtype: bool

这里有另一种方法:

df.loc[df['CODE'].isin(my_list).squeeze()]

最新更新