BO.*_*.LI 9 python comparison-operators dataframe pandas
我的问题是关于pandas用来比较具有"object"类型的列和整数的规则.这是我的代码:
In [334]: df
Out[334]:
c1 c2 c3 c4
id1 1 li -0.367860 5
id2 2 zhao -0.596926 5
id3 3 sun 0.493806 5
id4 4 wang -0.311407 5
id5 5 wang 0.253646 5
In [335]: df < 2
Out[335]:
c1 c2 c3 c4
id1 True True True False
id2 False True True False
id3 False True True False
id4 False True True False
id5 False True True False
In [336]: df.dtypes
Out[336]:
c1 int64
c2 object
c3 float64
c4 int64
dtype: object
Run Code Online (Sandbox Code Playgroud)
为什么"c2"专栏True适合所有人?
PS我也尝试过:
In [333]: np.less(np.array(["s","b"]),2)
Out[333]: NotImplemented
Run Code Online (Sandbox Code Playgroud)
对于DataFrames,与标量的比较始终返回具有所有布尔列的DataFrame.
我不认为它在官方的任何地方都有记录,但是源代码中有一条评论(见下文)确认了预期的行为:
[for]布尔比较[在DataFrame和标量之间]我们希望允许所有列(无论dtype是否通过)请参阅#4537进行讨论.
实际上,这意味着每列的所有比较都必须返回True或False.任何无效比较(例如'li' < 2)都应默认为其中一个布尔值.
简而言之,熊猫开发者决定它应默认为True.
#4537中有一些关于此行为的讨论以及要使用的某些参数False,或者仅将比较限制为具有兼容类型的列,但是故障单已关闭且未更改任何代码.
如果您感兴趣,可以在ops.py中找到的内部方法中查看默认值用于无效比较的位置:
def _comp_method_FRAME(cls, func, special):
str_rep = _get_opstr(func, cls)
op_name = _get_op_name(func, special)
@Appender('Wrapper for comparison method {name}'.format(name=op_name))
def f(self, other):
if isinstance(other, ABCDataFrame):
# Another DataFrame
if not self._indexed_same(other):
raise ValueError('Can only compare identically-labeled '
'DataFrame objects')
return self._compare_frame(other, func, str_rep)
elif isinstance(other, ABCSeries):
return _combine_series_frame(self, other, func,
fill_value=None, axis=None,
level=None, try_cast=False)
else:
# straight boolean comparisons we want to allow all columns
# (regardless of dtype to pass thru) See #4537 for discussion.
res = self._combine_const(other, func,
errors='ignore',
try_cast=False)
return res.fillna(True).astype(bool)
f.__name__ = op_name
return f
Run Code Online (Sandbox Code Playgroud)
该else块是我们对标量情况感兴趣的块.
注意errors='ignore'参数,意味着将返回无效比较NaN(而不是引发错误).该res.fillna(True)填充这些失败的比较True.