numpy广播和
我的数据框中有几列,其中有值。如果这些值存在于同一行中的另一组列中,我只想将这些值保留在这些列中。否则,我想将值设置为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
很难形成搜索以搜索谷歌的查询,而我获得的最接近就是这样使用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
似乎有些有用,但是我不确定这是正确的路径还是该如何处理。
numpy广播和 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
少numpy
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']))
]
您需要两个掩码,它们之间有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