我的数据框中有几列具有值。如果它们存在于同一行的另一组列中,我只希望将这些值保留在这些列中。否则,我想将值设置为NaN
。
这是一个示例数据框:
A B C D
0 1 30 1 29
1 5 42 99 5
2 64 67 12 22
3 2 22 22 0
4 43 6 9 43
在这种情况下,我希望根据C
和D
来更改A
和B
:
A B C D
0 1 30 1.0 NaN
1 5 42 NaN 5.0
2 64 67 NaN NaN
3 2 22 22.0 NaN
4 43 6 NaN 43.0
很难用Google来查询,而我最近得到的是像这样使用pandas.DataFrame.isin
:
from operator import concat
first = df.head(1)
first[['C', 'D']].isin(reduce(concat, first[['A', 'B']].values.tolist()))
哪个给我这个:
C D
0 True False
这似乎很有用,但是我不确定这是正确的路径还是从这里开始的处理方法。
答案 0 :(得分:3)
pd.DataFrame.where
cd = df[['C', 'D']].to_numpy()
ab = df[['A', 'B']].to_numpy()
df[['C', 'D']] = df[['C', 'D']].where((cd[..., None] == ab[:, None]).any(axis=2))
df
A B C D
0 1 30 1.0 NaN
1 5 42 NaN 5.0
2 64 67 NaN NaN
3 2 22 22.0 NaN
4 43 6 NaN 43.0
df[['C', 'D']] = [
(c if c in ab else np.nan, d if d in ab else np.nan)
for *ab, c, d in zip(*map(df.get, df))
]
df
A B C D
0 1 30 1.0 NaN
1 5 42 NaN 5.0
2 64 67 NaN NaN
3 2 22 22.0 NaN
4 43 6 NaN 43.0
相同,但列更具体
df[['C', 'D']] = [
(c if c in ab else np.nan, d if d in ab else np.nan)
for *ab, c, d in zip(*map(df.get, ['A', 'B', 'C', 'D']))
]
答案 1 :(得分:2)
您需要两个遮罩,它们之间有A
和B
和OR
。
m1 = df[['C', 'D']] == pd.DataFrame({'C':df['A'], 'D':df['A']})
m2 = df[['C', 'D']] == pd.DataFrame({'C':df['B'], 'D':df['B']})
df[['C', 'D']] = df[['C', 'D']][(m1 | m2)]
输出:
A B C D
0 1 30 1.0 NaN
1 5 42 NaN 5.0
2 64 67 NaN NaN
3 2 22 22.0 NaN
4 43 6 NaN 43.0