我想屏蔽索引与列名相同的Pandas DataFrame中的值。例如:
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的方式进行操作而无需迭代。
答案 0 :(得分:3)
尝试使用pd.DataFrame.apply将条件应用于与索引与系列/列名称匹配的每个数据框列。 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
此外,inspired by @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
答案 1 :(得分:2)
使用DataFrame.stack
和index.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
答案 2 :(得分: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