Pandas - 仅当多个列为空时,才用另一列的值填充一列

Pandas - fill a column with value from another column only when MULTIPLE COLUMNs are null

我有一个这样的 Pandas DataFrame:

   a      b    c      x    a1     b1     c1     x1
0  aa    ba   ca      9    NaN    NaN    NaN    1
1  ab    bb   cb      9    NaN    NaN    NaN    NaN
2  ac    bc   cd    NaN    NaN    NaN    NaN    NaN
3  ad    bd   cd      9    1      NaN    NaN    NaN
4  ae    be   ce      9    NaN    2      NaN    12
5  af    bf   cf      9    NaN    NaN    3      14
6  ag    bg   cg      9    3      NaN    1      45

我想做:

   a      b    c      x    a1     b1     c1     x1
0  aa    ba   ca      9    NaN    NaN    NaN    1
1  ab    bb   cb      9    NaN    NaN    NaN    9
2  ac    bc   cc    NaN    NaN    NaN    NaN    NaN
3  ad    bd   cd      9    1      NaN    NaN    NaN
4  ae    be   ce      9    NaN    2      NaN    12
5  af    bf   cf      9    NaN    NaN    3      14
6  ag    bg   cg      9    3      NaN    1      45

解释:

第 0 行: 我不希望替换发生,当 x1 中已经有一个值时,即使所有 a1, b1c1NaNs.
第 1 行和第 2 行: 我想用 x 中的任何内容填充第 x1 列,仅当列 a1b1c1NaNs.
第 3、4、5 和 6 行: 我希望列 x1 保持原样,当来自 a1、[=17= 的任何一列或两列时] 和 c1NaNs.

有没有有效的方法来做这个操作?


我已按照 and Whosebug 答案中所示进行了尝试,但出现广播错误,可能是因为我正在尝试对多个列进行检查。

这是我尝试过的方法:

np.where(np.isnan(df[['a1', 'b1', 'c1']].values), df['x'].values, df['x1'].values)

我的错误:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-32-bb6a0f9faf18> in <module>
----> 1 np.where(np.isnan(df[['a', 'b', 'c']].values), df['x'].values, df['x1'].values)

<__array_function__ internals> in where(*args, **kwargs)

ValueError: operands could not be broadcast together with shapes (176213,6) (176213,) (176213,) 

一种选择是在 axis=1:

上使用 any
df['x1'] = np.where(df[['a1', 'b1', 'c1', 'x1']].any(axis=1), df['x1'], df['x'])

df:

    a   b   c    x   a1   b1   c1    x1
0  aa  ba  ca  9.0  NaN  NaN  NaN   1.0
1  ab  bb  cb  9.0  NaN  NaN  NaN   9.0
2  ac  bc  cd  NaN  NaN  NaN  NaN   NaN
3  ad  bd  cd  9.0  1.0  NaN  NaN   NaN
4  ae  be  ce  9.0  NaN  2.0  NaN  12.0
5  af  bf  cf  9.0  NaN  NaN  3.0  14.0
6  ag  bg  cg  9.0  3.0  NaN  1.0  45.0

通过 的另一个选项:

df.loc[~df[['a1', 'b1', 'c1', 'x1']].any(1), 'x1'] = df['x']

否定any而不是使用all的原因是any会认为NaN是假的,而all会认为NaN 如实:

pd.Series([np.nan, np.nan]).any()  # False
pd.Series([np.nan, np.nan]).all()  # True