这行中的“<”在做什么?:data += dt < b

What is the '<' doing in this line?: data += dt < b

输入:

dt    = [6,7,8,9,10]
data  = [1,2,3,4,5]

b     = 8.0
b     = np.require(b, dtype=np.float)

data  += dt  < b
data

输出:

array([2, 3, 3, 4, 5])

我尝试输入不同的数字,但仍然无法弄清楚“<”在那里做什么.... 此外,它似乎仅在 b 为 np.float 时才有效(因此转换)。

< 与 numpy 数组进行逐元素比较。这意味着它 returns 一个数组,其中有一个 True 条件为真, False 如果不是。 np.require 行在这里是必需的,因此它实际上使用了 NumPy 数组。如果您事先将 datadt 转换为 np.array,则可以删除 np.require

然后将结果添加(按元素)到数值数组。在这种情况下,True 等于 1,False 等于 0。

>>> dt < b  # which elements are smaller than b?
array([ True,  True, False, False, False])

>>> 0 + (dt  < b)  # boolean arrays in arithmetic operations with numbers
array([1, 1, 0, 0, 0])

所以data的每个元素都加1,其中dt的元素小于8。

这只是等效函数的别名(或快捷方式或便利符号):numpy.less()

In [116]: arr1 = np.arange(8)
In [117]: scalar = 6.0

# comparison that generates a boolean mask
In [118]: arr1 < scalar
Out[118]: array([ True,  True,  True,  True,  True,  True, False, False])

# same operation as above 
In [119]: np.less(arr1, scalar)
Out[119]: array([ True,  True,  True,  True,  True,  True, False, False])

让我们看看在这种情况下如何将这个布尔数组添加到非布尔数组。可能是由于类型强制

# sample array
In [120]: some_arr = np.array([1, 1, 1, 1, 1, 1, 1, 1])

# addition after type coercion 
In [122]: some_arr + (arr1 < scalar)
Out[122]: array([2, 2, 2, 2, 2, 2, 1, 1])

# same output achieved with `numpy.less()`
In [123]: some_arr + np.less(arr1, scalar)
Out[123]: array([2, 2, 2, 2, 2, 2, 1, 1])

因此,类型强制发生在布尔数组上,然后执行加法。

dt 是一个列表:

In [50]: dt    = [6,7,8,9,10]
In [51]: dt < 8
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-51-3d06f93227f5> in <module>()
----> 1 dt < 8

TypeError: '<' not supported between instances of 'list' and 'int'

< (.__lt__) 没有为列表定义。

但如果比较的一个元素是 ndarray,则 __lt__ 的 numpy 定义适用。 dt转成数组,逐个元素比较

In [52]: dt < np.array(8)
Out[52]: array([ True,  True, False, False, False])
In [53]: np.array(dt) < 8
Out[53]: array([ True,  True, False, False, False])

numpy数组操作也解释了data +=部分:

In [54]: data  = [1,2,3,4,5]          # a list
In [55]: data + (dt < np.array(8))    # list=>array, and boolean array to integer array
Out[55]: array([2, 3, 3, 4, 5])
In [56]: data
Out[56]: [1, 2, 3, 4, 5]
In [57]: data += (dt < np.array(8))
In [58]: data
Out[58]: array([2, 3, 3, 4, 5])

实际上,我有点惊讶 += data 已从列表更改为数组。这意味着 data+=... 已作为赋值实现:

data = data + (dt <np.array(8))

通常 + 列表是一个连接:

In [61]: data += ['a','b','c']
In [62]: data
Out[62]: [1, 2, 3, 4, 5, 'a', 'b', 'c']
# equivalent of: data.extend(['a','b','c'])

您通常可以在数组上下文中使用列表,但最好将对象设为数组,这样您就可以获得这些隐式的、有时是意外的转换。