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
, b1
和 c1
是 NaN
s.
第 1 行和第 2 行: 我想用 x
中的任何内容填充第 x1
列,仅当列 a1
、b1
和 c1
是 NaN
s.
第 3、4、5 和 6 行: 我希望列 x1
保持原样,当来自 a1
、[=17= 的任何一列或两列时] 和 c1
是 NaN
s.
有没有有效的方法来做这个操作?
我已按照 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
我有一个这样的 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
, b1
和 c1
是 NaN
s.
第 1 行和第 2 行: 我想用 x
中的任何内容填充第 x1
列,仅当列 a1
、b1
和 c1
是 NaN
s.
第 3、4、5 和 6 行: 我希望列 x1
保持原样,当来自 a1
、[=17= 的任何一列或两列时] 和 c1
是 NaN
s.
有没有有效的方法来做这个操作?
我已按照
这是我尝试过的方法:
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