Numpy 可能会导致意外的错误点
介绍
在使用NumPy时,有些特殊情况不同于Python,可能会导致意外的错误。这篇文章将列举出一些值得注意的问题,提醒使用者避免一些常见错误。
阅读更多:Numpy 教程
数组运算的细节
- 数组广播
NumPy的数组广播是一种强大的功能,能够使人们无须创建重复的数组即可对不同大小的数组进行运算,但需要遵循一些规则。这里介绍三个规则:
-
规则1:如果操作数的维数不相等,则在数组较小的末尾补1,直到它们的行和列统一。
“`python
import numpy as np
a = np.array([1, 2, 3])
b = np.array([[4, 5, 6], [7, 8, 9]])
print(a.shape)
print(b.shape)
print(a + b)
# Output:
# (3,)
# (2, 3)
# [[ 5 7 9]
# [ 8 10 12]]
“` -
规则2:对于任何两个维度,如果它们的大小不相等,其中大小为1的维度会被拉伸为另一个形状大小相等的维度。
“`python
a = np.array([[1, 2, 3]])
b = np.array([[4], [5], [6]])
print(a.shape)
print(b.shape)
print(a + b)
# Output:
# (1, 3)
# (3, 1)
# [[5 6 7]
# [6 7 8]
# [7 8 9]]
“` -
规则3:如果两个操作数在某个维度上的大小都不等于1,这两个数组就不兼容了
-
预算符的dtype规则
在NumPy中,可以使用预算符来计算两个数组,但是可能会出现意外的结果。这是因为NumPy遵循一定的dtype规则,将更高精度的dtype转换为较低精度的dtype。
a = np.array([1, 2, 3], dtype=np.int64) b = np.array([4, 5, 6], dtype=np.int32) print(a.dtype) print(b.dtype) print(a + b) # Output: # int64 # int32 # [5 7 9]
高级索引的细节
- 布尔索引与花式索引的结合
在NumPy数组中,可以使用布尔索引和花式索引来选择需要的元素,但是在结合使用时,需要特别注意。如果使用花式索引来修改数组时,需要显示的将非布尔索引的维度进行复制。
a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) b = np.array([True, False, True]) print(a[b, :]) # Output: # [[1 2 3] # [7 8 9]] a[b, :] = 0 # Error!这种方式造成的错误可以在使用np.ix_()函数时避免。
a[np.ix_(b, np.arange(3))] = 0 # Correct! - 重复索引
在使用花式索引时,我们可以重复索引,但是这样也可能会产生出乎意料的结果,因为重复的索引会导致结果多于一个。
a = np.array([1, 2, 3, 4, 5, 6]) print(a[[0, 0, 1, 1]]) # Output: # [1 1 2 2]如果使用重复索引,在索引中使用unique()函数可以去除重复的元素。
print(np.unique(a[[0, 0, 1, 1]])) # Output: # [1 2]
非随机数据
NumPy还有一些关于非随机数组的特殊规则,包括:
- nan的处理
在NumPy中,nan表示无穷大小的数量或者未定义(Undefined)。与其他数字类型不同,当nan参与计算时,结果总是nan。因此,应该避免在对数组进行运算时将nan与其他数字混合。
a = np.array([1, 2, np.nan, 3]) b = np.array([4, 5, 6, 7]) print(a * b) # nan everywhere当处理包含nan的数组时,应该使用函数中的特殊方法,如Numpy中的nanmean(),来跳过nan所表示的数据。
-
零除错误
在NumPy中,除以零将导致Inf和 – Inf的出现。Inf是表示“正无穷大”的特殊标记。
a = np.array([1, 2, 3, 4, 5]) b = np.array([0, 0, 0, 0, 0]) print(a / b) # inf everywhere使用不同符号的零,会导致不同的结果,需要特别注意。
a = np.array([1, 2, 3, 4, 5]) b = np.array([-1, 0, 1, 2, 3]) print(a / b) # [-1. -inf 3. 2.5 1.66666667]
总结
在使用NumPy时,需要特别注意高级索引、数组广播、dtype规则以及非随机数据所带来的细节问题。遵循这些规则,可以让NumPy的使用更加便捷,并避免常见的错误。
极客教程