熊猫:如果值存在于同一行的另一列中,则将它们保留在一组列中,否则将其设置为NaN

时间:2019-06-28 16:30:30

标签: python pandas dataframe

我的数据框中有几列具有值。如果它们存在于同一行的另一组列中,我只希望将这些值保留在这些列中。否则,我想将值设置为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

在这种情况下,我希望根据CD来更改AB

    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

这似乎很有用,但是我不确定这是正确的路径还是从这里开始的处理方法。

2 个答案:

答案 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)

您需要两个遮罩,它们之间有ABOR

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