根据列名等于索引屏蔽单元格(pandas)

3 投票
3 回答
890 浏览
提问于 2025-06-18 03:59

我想在一个Pandas数据框中,把那些行索引和列名相同的值隐藏掉。比如说:

import pandas as pd
import numpy as np

a = pd.DataFrame(np.arange(12).reshape((4, 3)),
                 index=["a", "b", "c", "d"],
                 columns=["a", "b", "c"])

   a   b   c
a  0   1   2
b  3   4   5
c  6   7   8
d  9  10  11

隐藏后的结果是:

   a   b   c
a NaN  1   2
b  3  NaN  5
c  6   7  NaN
d  9  10  11

这看起来很简单,但我不太确定怎么用Python的方式做到这一点,而不需要一个一个地去处理。

相关问题:

  • 暂无相关问题
暂无标签

3 个回答

2

使用 DataFrame.stackindex.get_level_values

st = a.stack()
m = st.index.get_level_values(0) == st.index.get_level_values(1) 
a = st.mask(m).unstack()

     a     b     c
a  NaN   1.0   2.0
b  3.0   NaN   5.0
c  6.0   7.0   NaN
d  9.0  10.0  11.0
5

试着使用 pd.DataFrame.apply 来对每一列数据进行条件判断,这个条件是根据索引和列名来匹配的。使用这个方法后,你会得到一个布尔类型的数据框,然后可以用 pd.DataFrame.mask 来处理这些数据:

a.mask(a.apply(lambda x: x.name == x.index))

输出结果:

     a     b     c
a  NaN   1.0   2.0
b  3.0   NaN   5.0
c  6.0   7.0   NaN
d  9.0  10.0  11.0

另外,受 @QuangHoang 的启发,你还可以使用 np.equal.outer 来实现:

a.mask(np.equal.outer(a.index, a.columns)) 

输出结果:

     a     b     c
a  NaN   1.0   2.0
b  3.0   NaN   5.0
c  6.0   7.0   NaN
d  9.0  10.0  11.0
2

你也可以使用广播功能:

a.mask(a.index[:,None] == a.columns[None,:])

或者

a.mask(a.index.values[:,None] == a.columns.values[None,:])

输出结果:

     a     b     c
a  NaN   1.0   2.0
b  3.0   NaN   5.0
c  6.0   7.0   NaN
d  9.0  10.0  11.0

撰写回答