我正在尝试基于Nan是常见的串联整数比较来创建虚拟变量。 A>如果存在任何Nan值,则比较会引发错误,但我希望比较返回Nan。我知道我可以使用fillna()来替换Nan,我知道这个值是假的,但我希望有更优雅的方法来做到这一点。我需要更改fillna()中的值,如果我使用少于,或使用可能是正面或负面的变量,这是另一个创建错误的机会。有没有办法让30< Nan = Nan?
要明确,我想要这个:
df['var_dummy'] = df[df['var'] >= 30].astype('int')
如果var为null则返回null;如果是30+则返回1,否则返回0。目前我得到ValueError:无法从重复的轴重新索引。
答案 0 :(得分:4)
这是一种方式:
s1 = pd.Series([1, 3, 4, 2, np.nan, 5, np.nan, 7])
s2 = pd.Series([2, 1, 5, 5, np.nan, np.nan, 2, np.nan])
(s1 < s2).mask(s1.isnull() | s2.isnull(), np.nan)
Out:
0 1.0
1 0.0
2 1.0
3 1.0
4 NaN
5 NaN
6 NaN
7 NaN
dtype: float64
如果其中任何一个是NaN,则会屏蔽从(s1 < s2)
返回的布尔数组。在这种情况下,它返回NaN。但是你不能在一个布尔数组中使用NaN,因此它将被转换为float。
答案 1 :(得分:0)
解决方案1
df['var_dummy'] = 1 * df.loc[~pd.isnull(df['var']), 'var'].ge(30)
解决方案2
df['var_dummy'] = df['var'].apply(lambda x: np.nan if x!=x else 1*(x>30))
x!=x
等同于math.isnan()
答案 2 :(得分:0)
您可以使用notna()方法。这是一个示例:
import pandas as pd
list1 = [12, 34, -4, None, 45]
list2 = ['a', 'b', 'c', 'd', 'e']
# Calling DataFrame constructor on above lists
df = pd.DataFrame(list(zip(list1, list2)), columns =['var1','letter'])
#Assigning new dummy variable:
df['var_dummy'] = df['var1'][df['var1'].notna()] >= 30
# or you can also use: df['var_dummy'] = df.var1[df.var1.notna()] >= 30
df
将产生以下输出:
var1 letter var_dummy
0 12.0 a False
1 34.0 b True
2 -4.0 c False
3 NaN d NaN
4 45.0 e True
因此,新的虚拟变量具有原始变量NaN行的NaN值。 唯一与您的请求不匹配的是,虚拟变量采用的是False和True值,而不是0和1,但是您可以轻松地重新分配值。
但是,您不能更改的是,新的虚拟变量必须为浮点型,因为它包含NaN值,而NaN值本身就是一个特殊的浮点值。 有关NaN float的更多信息,请参见此处: How can I check for NaN values?
在这里: https://towardsdatascience.com/navigating-the-hell-of-nans-in-python-71b12558895b