处理 np.select 中的缺失值
Handle missing values in np.select
我正在尝试为我的熊猫DataFrame
设置一个新的专栏'Score'
我发现最好的方法是使用 np.select()
函数。
然而,我的数据框中有一些缺失值,我想 return False,但找不到这样做的方法。
我最后一次尝试如下所示:
score_conditions = [
((df['column1']).replace({'<NA>': np.nan}).fillna(False) > 15),
(df['column2'] > 5),
(df['column3'] < 1)
]
score_choices = [3, 2, 1]
df['Score'] = np.select(score_conditions, score_choices, default=0)
我对 panda 的 NA 和 numpy NaN 之间的差异感到有点迷茫,这可能是不同的?
当前 <NA>
通常是 Int64 列的一部分。
我在大多数列中都有缺失值(10 个条件列中可能有 5 个),但仍然希望在有 1 个或多个值可用时计算分数。
这是一个示例数据框:
df = DataFrame({'column1' : [5,16,<NA>,24], 'column2' : [5,6,3,1], 'column3' : [<NA>,0,0,<NA>]})
预期结果为:
For index 0: 0 #zero condition are met, when values are available
For index 1: 3 #all conditions are met
For index 2: 1 #only condition in 3rd columns is met, when values are available
For index 3: 1 #only condition in 1st columns is met, when values are available
谢谢,
第一个想法是升级 pandas 到最新版本。
另一个想法是通过将值转换为浮点数将 NA
转换为 np.nan
:
df['column1'] > 15
至:
df['column1'].astype(float) > 15
我认为这可能是次要的语法问题。基本上,应该用双引号引起来,因为它不是原生的 python 或 pandas 或 numpy 数据类型。此时,列变为 type('O') 表示它们是对象。我稍微修改了你的代码并得到了答案,虽然它不是理想的分数值,但它完全按照设计工作:
df = pd.DataFrame({'column1' : [5,16,"<NA>",24], 'column2' : [5,6,3,1], 'column3' : ["<NA>",0,0,"<NA>"]})
score_conditions = [
((df['column1']).replace({'<NA>': np.nan}).fillna(False) > 15),
(df['column2'] > 5),
(df['column3'].replace({'<NA>': np.nan}).fillna(False) < 1)
]
score_choices = [3, 2, 1]
df['Score'] = np.select(score_conditions, score_choices, default=0)
数据类型很重要,无论如何 fillna
就是您所需要的。
让我们用你的例子:
df = pd.DataFrame({'column1' : [5,16,pd.NA,24], 'column2' : [5,6,3,1], 'column3' : [pd.NA,0,0,pd.NA]})
>>> score_conditions = [
(df['column1'] > 15),
(df['column2'] > 5),
(df['column3'] < 1)
]
>>> for i in score_conditions: print(i)
0 False
1 True
2 False
3 True
Name: column1, dtype: bool
0 False
1 True
2 False
3 False
Name: column2, dtype: bool
0 False
1 True
2 True
3 False
Name: column3, dtype: bool
您直接获得预期值,因为列具有 object
数据类型:
>>> print(df.dtypes)
column1 object
column2 int64
column3 object
dtype: object
但是您在评论中解释说您的列具有 Int64
数据类型(注意大写 I)。因此,让我们强制使用该数据类型:
>>> df = pd.DataFrame({'column1' : [5,16,pd.NA,24], 'column2' : [5,6,3,1], 'column3' : [pd.NA,0,0,pd.NA]}, dtype=pd.Int64Dtype())
>>> score_conditions = [
(df['column1'] > 15),
(df['column2'] > 5),
(df['column3'] < 1)
]
>>> for i in score_conditions: print(i)
0 False
1 True
2 <NA>
3 True
Name: column1, dtype: boolean
0 False
1 True
2 False
3 False
Name: column2, dtype: boolean
0 <NA>
1 True
2 True
3 <NA>
Name: column3, dtype: boolean
Patatras,我们找到了您想避免的 <NA>
值!至少它重现了你的问题...
解决方法是fillna
:
>>> score_conditions = [
(df['column1'] > 15).fillna(False),
(df['column2'] > 5).fillna(False),
(df['column3'] < 1).fillna(False)
]
>>> for i in score_conditions: print(i)
0 False
1 True
2 False
3 True
Name: column1, dtype: boolean
0 False
1 True
2 False
3 False
Name: column2, dtype: boolean
0 False
1 True
2 True
3 False
Name: column3, dtype: boolean
并且不需要浮点数转换...
我正在尝试为我的熊猫DataFrame
设置一个新的专栏'Score'
我发现最好的方法是使用 np.select()
函数。
然而,我的数据框中有一些缺失值,我想 return False,但找不到这样做的方法。
我最后一次尝试如下所示:
score_conditions = [
((df['column1']).replace({'<NA>': np.nan}).fillna(False) > 15),
(df['column2'] > 5),
(df['column3'] < 1)
]
score_choices = [3, 2, 1]
df['Score'] = np.select(score_conditions, score_choices, default=0)
我对 panda 的 NA 和 numpy NaN 之间的差异感到有点迷茫,这可能是不同的?
当前 <NA>
通常是 Int64 列的一部分。
我在大多数列中都有缺失值(10 个条件列中可能有 5 个),但仍然希望在有 1 个或多个值可用时计算分数。
这是一个示例数据框:
df = DataFrame({'column1' : [5,16,<NA>,24], 'column2' : [5,6,3,1], 'column3' : [<NA>,0,0,<NA>]})
预期结果为:
For index 0: 0 #zero condition are met, when values are available
For index 1: 3 #all conditions are met
For index 2: 1 #only condition in 3rd columns is met, when values are available
For index 3: 1 #only condition in 1st columns is met, when values are available
谢谢,
第一个想法是升级 pandas 到最新版本。
另一个想法是通过将值转换为浮点数将 NA
转换为 np.nan
:
df['column1'] > 15
至:
df['column1'].astype(float) > 15
我认为这可能是次要的语法问题。基本上,应该用双引号引起来,因为它不是原生的 python 或 pandas 或 numpy 数据类型。此时,列变为 type('O') 表示它们是对象。我稍微修改了你的代码并得到了答案,虽然它不是理想的分数值,但它完全按照设计工作:
df = pd.DataFrame({'column1' : [5,16,"<NA>",24], 'column2' : [5,6,3,1], 'column3' : ["<NA>",0,0,"<NA>"]})
score_conditions = [
((df['column1']).replace({'<NA>': np.nan}).fillna(False) > 15),
(df['column2'] > 5),
(df['column3'].replace({'<NA>': np.nan}).fillna(False) < 1)
]
score_choices = [3, 2, 1]
df['Score'] = np.select(score_conditions, score_choices, default=0)
数据类型很重要,无论如何 fillna
就是您所需要的。
让我们用你的例子:
df = pd.DataFrame({'column1' : [5,16,pd.NA,24], 'column2' : [5,6,3,1], 'column3' : [pd.NA,0,0,pd.NA]})
>>> score_conditions = [
(df['column1'] > 15),
(df['column2'] > 5),
(df['column3'] < 1)
]
>>> for i in score_conditions: print(i)
0 False
1 True
2 False
3 True
Name: column1, dtype: bool
0 False
1 True
2 False
3 False
Name: column2, dtype: bool
0 False
1 True
2 True
3 False
Name: column3, dtype: bool
您直接获得预期值,因为列具有 object
数据类型:
>>> print(df.dtypes)
column1 object
column2 int64
column3 object
dtype: object
但是您在评论中解释说您的列具有 Int64
数据类型(注意大写 I)。因此,让我们强制使用该数据类型:
>>> df = pd.DataFrame({'column1' : [5,16,pd.NA,24], 'column2' : [5,6,3,1], 'column3' : [pd.NA,0,0,pd.NA]}, dtype=pd.Int64Dtype())
>>> score_conditions = [
(df['column1'] > 15),
(df['column2'] > 5),
(df['column3'] < 1)
]
>>> for i in score_conditions: print(i)
0 False
1 True
2 <NA>
3 True
Name: column1, dtype: boolean
0 False
1 True
2 False
3 False
Name: column2, dtype: boolean
0 <NA>
1 True
2 True
3 <NA>
Name: column3, dtype: boolean
Patatras,我们找到了您想避免的 <NA>
值!至少它重现了你的问题...
解决方法是fillna
:
>>> score_conditions = [
(df['column1'] > 15).fillna(False),
(df['column2'] > 5).fillna(False),
(df['column3'] < 1).fillna(False)
]
>>> for i in score_conditions: print(i)
0 False
1 True
2 False
3 True
Name: column1, dtype: boolean
0 False
1 True
2 False
3 False
Name: column2, dtype: boolean
0 False
1 True
2 True
3 False
Name: column3, dtype: boolean
并且不需要浮点数转换...