我有一些缺少某些值的数据框:
A B
0 63.0 9.0
1 NaN 35.0
2 51.0 95.0
3 25.0 11.0
4 91.0 NaN
5 2.0 47.0
6 37.0 10.0
7 NaN 88.0
8 75.0 87.0
9 92.0 21.0
我想根据以上两列的条件创建一个新列:
df['C'] = numpy.where((df['A']>55) | (df['B']>55), "Yes", "No")
这可行,但未考虑缺失值:
A B C
0 63.0 9.0 Yes
1 NaN 35.0 No
2 51.0 95.0 Yes
3 25.0 11.0 No
4 91.0 NaN Yes
5 2.0 47.0 No
6 37.0 10.0 No
7 NaN 88.0 Yes
8 75.0 87.0 Yes
9 92.0 21.0 Yes
要纠正缺失值,我必须运行以下代码:
df['C'] = numpy.where((df['A'].isnull()) | (df['B'].isnull()), numpy.nan, df['C'])
然后我将获得适当的新列:
A B C
0 63.0 9.0 Yes
1 NaN 35.0 NaN
2 51.0 95.0 Yes
3 25.0 11.0 No
4 91.0 NaN NaN
5 2.0 47.0 No
6 37.0 10.0 No
7 NaN 88.0 NaN
8 75.0 87.0 Yes
9 92.0 21.0 Yes
有没有更好的方法,以便我仅可以纠正单行代码中的缺失值?
答案 0 :(得分:4)
使用 np.select
。条件 的顺序在这里很重要,因为np.select
选择了第一个有效选项,因此您必须先进行空检查。
c1 = df.isnull().any(1)
c2 = df.gt(55).any(1)
df['C'] = np.select([c1, c2], [np.nan, 'Yes'], 'No')
A B C
0 63.0 9.0 Yes
1 NaN 35.0 nan
2 51.0 95.0 Yes
3 25.0 11.0 No
4 91.0 NaN nan
5 2.0 47.0 No
6 37.0 10.0 No
7 NaN 88.0 nan
8 75.0 87.0 Yes
9 92.0 21.0 Yes
答案 1 :(得分:3)
根据要执行多少列操作,这会变得有些复杂。
这是map
和mask
的替代选择:
(df[['A', 'B']]
.gt(55)
.any(1)
.map(lambda x: 'Yes' if x else 'No') # .map({True : 'Yes', False : 'No'}.__getitem__)
.mask(df[['A', 'B']].isna().any(1))
)
0 Yes
1 NaN
2 Yes
3 No
4 NaN
5 No
6 No
7 NaN
8 Yes
9 Yes
dtype: object
这仍然是一条语句,为了便于阅读,它分为多行。
答案 2 :(得分:3)
束缚两个any
和map
(df>55).any(1).mask((df.isnull()).any(1),np.nan).map({1:'Yes',0:'No'})
Out[405]:
0 Yes
1 NaN
2 Yes
3 No
4 NaN
5 No
6 No
7 NaN
8 Yes
9 Yes
dtype: object
或使用两个np.where
a=(df>55).any(1)
b=df.isnull().any(1)
np.where(b,np.nan,np.where(a,'Yes','No'))
Out[407]:
array(['Yes', 'nan', 'Yes', 'No', 'nan', 'No', 'No', 'nan', 'Yes', 'Yes'],
dtype='<U32')
答案 3 :(得分:2)
IMO,如果我们想忽略NaN行,我们就删除它们。分配将与索引对齐,从而导致缺少索引的NaN。
In [317]: df["C"] = (df[["A","B"]].dropna() > 55).any(axis=1).replace(
{False: "No", True: "Yes"})
In [318]: df
Out[318]:
A B C
0 63.0 9.0 Yes
1 NaN 35.0 NaN
2 51.0 95.0 Yes
3 25.0 11.0 No
4 91.0 NaN NaN
5 2.0 47.0 No
6 37.0 10.0 No
7 NaN 88.0 NaN
8 75.0 87.0 Yes
9 92.0 21.0 Yes