如何在Pandas(Python 2.7)中创建虚拟变量已被多次询问,但我还不知道强大且快速的解决方案。考虑一下这个数据框:
df=pd.DataFrame({'A':[1,2,-1,np.nan, 'rh']})
df
Out[9]:
A
0 1
1 2
2 -1
3 NaN
4 rh
是的,它有混合类型。随时都有大数据集(我有数百万行)
我需要创建虚拟变量,如果条件为真,则为1,否则为零。我假设如果Pandas无法执行逻辑比较(比如比较字符串是否大于某个实数),我会得到零。请看一下:
df['dummy2']=(df.A > 0).astype(int)
df['dummy1']=np.where(df.A>0,1,0)
df
Out[12]:
A dummy2 dummy1
0 1 1 1
1 2 1 1
2 -1 0 0
3 NaN 0 0
4 rh 1 1
显然这是有问题的。这里发生了什么?我怎样才能防止这些错误的旗帜?
非常感谢!
答案 0 :(得分:4)
你可以采取两种方式
In [37]: pd.to_numeric(df.A, errors='coerce').notnull() & (df.A > 0)
Out[37]:
0 True
1 True
2 False
3 False
4 False
Name: A, dtype: bool
In [38]: df.A.apply(np.isreal) & (df.A > 0)
Out[38]:
0 True
1 True
2 False
3 False
4 False
Name: A, dtype: bool
第三个可能很慢
In [39]: df.A.str.isnumeric().isnull() & (df.A > 0)
Out[39]:
0 True
1 True
2 False
3 False
4 False
Name: A, dtype: bool
答案 1 :(得分:2)
更新:@JohnGalt在评论中指出,更好的方法是将pd.to_numeric
与errors='coerce'
一起使用:
# Your condition here, instead of `> 0`, using the fact that NaN > 0 == false
[18]: df['dummy1'] = (pd.to_numeric(df.A, errors='coerce').notnull() > 0).astype('int')
[19]: df
Out[19]:
A dummy1
0 1 1
1 2 1
2 -1 0
3 NaN 0
4 rh 0
最好的方法创建这样的虚拟变量的一般方法是:
def foo(a):
try:
tmp = int(a)
return 1 if tmp > 0 else 0 # Your condition here.
except:
return 0
[12]: df.A.map(foo)
Out[12]:
0 1
1 1
2 1
3 0
4 0
Name: A, dtype: int64
您正在使用Python comparisons between str
and int
are (unfortunately) allowed进行操作。 Python 3上的操作失败:
[5]: df.A > 0
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-5-890e73655a37> in <module>()
----> 1 df.A > 0
/home/utkarshu/miniconda3/envs/py35/lib/python3.5/site-packages/pandas/core/ops.py in wrapper(self, other, axis)
724 other = np.asarray(other)
725
--> 726 res = na_op(values, other)
727 if isscalar(res):
728 raise TypeError('Could not compare %s type with Series'
/home/utkarshu/miniconda3/envs/py35/lib/python3.5/site-packages/pandas/core/ops.py in na_op(x, y)
646 result = lib.vec_compare(x, y, op)
647 else:
--> 648 result = lib.scalar_compare(x, y, op)
649 else:
650
pandas/lib.pyx in pandas.lib.scalar_compare (pandas/lib.c:14186)()
TypeError: unorderable types: str() > int()