pandas 删除的列重新出现在列中,level

zqdjd7g9  于 2023-06-20  发布在  其他
关注(0)|答案(2)|浏览(182)

我有一个带有MultiIndex的DataFrame。
当我删除一个列(例如,包含一个NaN)时,当我调用df.columns.levels[1]时,这个列名仍然会出现。
最小工作示例:

# Create DataFrame
midx = pd.MultiIndex.from_tuples([('A','aa'),('A','bb'),('B','cc'),('B','dd')])
mydf = pd.DataFrame(np.random.randn(5,4), columns=midx)
mydf.loc[1,('B','cc')] = np.nan

print(mydf)

>>        A                   B          
         aa        bb        cc        dd
0 -0.565250 -1.267290 -1.811422 -0.242648
1  0.138827  0.182022       NaN -0.286807
2  0.037163 -1.867622  1.259539 -0.485333
3  1.283082  1.030154  0.678748 -0.200731
4 -0.405116 -0.963670 -0.405438 -1.695403

# Drop column with NaN
mydf.dropna(how='any', axis=1, inplace=True)

print(mydf)
>>        A                   B
         aa        bb        dd
0 -0.565250 -1.267290 -0.242648
1  0.138827  0.182022 -0.286807
2  0.037163 -1.867622 -0.485333
3  1.283082  1.030154 -0.200731
4 -0.405116 -0.963670 -1.695403

mydf.columns.levels[1]
>> Index(['aa', 'bb', 'cc', 'dd'], dtype='object')

我尝试过的替代方案,都以相同的结果结束:

new_df = mydf.dropna(how='any', axis=1)
new_df = mydf.dropna(how='any', axis=1).copy()

我需要访问级别1上的当前列名列表。我已经找到了一个可行的解决方法,但我需要理解为什么上面的代码不能按预期工作。

2ul0zpep

2ul0zpep1#

使用pd.MultiIndex.remove_unused_levels

mydf.columns.levels[1]
#Index(['aa', 'bb', 'cc', 'dd'], dtype='object')

mydf.columns = mydf.columns.remove_unused_levels()

mydf.columns.levels[1]
#Index(['aa', 'bb', 'dd'], dtype='object')
hlswsv35

hlswsv352#

不要被MultiIndex(单个索引的组合)和每个Index级别所迷惑。MultiIndex表示组成它的各个索引的可见子集(最多是笛卡尔积)。

# Index, level 0
>>> mydf.columns.levels[0]

# Index, level 1
>>> mydf.columns.levels[1]
Index(['aa', 'bb', 'cc', 'dd'], dtype='object')

# Values, level 0
>>> mydf.columns.get_level_values(0)
Index(['A', 'A', 'B'], dtype='object')

# Values, level 1
>>> mydf.columns.get_level_values(1)
Index(['aa', 'bb', 'dd'], dtype='object')

# Cartesian product / dense multi-index
>>> pd.MultiIndex.from_product([mydf.columns.levels[0], mydf.columns.levels[1]])
MultiIndex([('A', 'aa'),
            ('A', 'bb'),
            ('A', 'cc'),
            ('A', 'dd'),
            ('B', 'aa'),
            ('B', 'bb'),
            ('B', 'cc'),
            ('B', 'dd')],
           )

因此,如果您有一个不再引用的元素,正如@ScottBoston所说,您可以使用remove_unused_levels
为了仅用所使用的级别来重构MultiIndex,可以使用remove_unused_levels()方法。

>>> mydf.columns.remove_unused_levels().levels
FrozenList([['A', 'B'], ['aa', 'bb', 'dd']])
#      level 0 --^     level 1 --^

有关MultiIndex /高级索引中定义的级别的更多信息

相关问题