NumPy是Python顶用于数值打算的重要库,它供给了高效的数组操纵跟数学打算功能。在数据科学跟呆板进修范畴,NumPy的广泛利用使得数据处理跟分析变得愈加高效。但是,对大年夜型数据集或复杂打算,NumPy的机能可能成为瓶颈。本文将经由过程实战代码实例剖析,展示怎样优化NumPy代码,减速数据处理。
NumPy的元素范例(dtype)是其核心不雅点之一,正确抉择跟利用dtype可能明显进步内存效力跟打算速度。
以下是一些罕见的NumPy数据范例及其在内存占用跟打算速度上的差别:
import numpy as np
# int8: 8位有标记整数
int8_arr = np.array([1, 2, 3], dtype=np.int8)
# int16: 16位有标记整数
int16_arr = np.array([1, 2, 3], dtype=np.int16)
# int32: 32位有标记整数
int32_arr = np.array([1, 2, 3], dtype=np.int32)
# int64: 64位有标记整数
int64_arr = np.array([1, 2, 3], dtype=np.int64)
# uint8: 8位无标记整数
uint8_arr = np.array([1, 2, 3], dtype=np.uint8)
# uint16: 16位无标记整数
uint16_arr = np.array([1, 2, 3], dtype=np.uint16)
# uint32: 32位无标记整数
uint32_arr = np.array([1, 2, 3], dtype=np.uint32)
# uint64: 64位无标记整数
uint64_arr = np.array([1, 2, 3], dtype=np.uint64)
# 利用int8范例增加内存占用
large_array = np.random.randint(0, 256, size=1000000)
large_array = large_array.astype(np.int8)
print(large_array.nbytes) # 输出:5000000
# 利用int64范例停止打算减速
large_array = np.random.randint(0, 1000000000, size=1000000)
result = np.sum(large_array.astype(np.int64))
print(result)
NumPy中的函数跟操纵都是针对全部数组停止的,而不是一一元素停止操纵。如许可能避免利用for轮返来遍历数组,并且可能利用底层优化实现高效的打算。
import numpy as np
# 创建两个数组
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
# 利用向量化操纵打算两个数组的跟
c = a + b
print(c) # 输出:[5 7 9]
NumPy中的播送功能可能主动处理差别外形的数组之间的运算,而无需显式地编写轮回。播送可能将较小的数组主动扩大年夜为较大年夜的数组,以便停止元素级其余操纵。
import numpy as np
# 创建一个数组跟一个标量
a = np.array([1, 2, 3])
b = 2
# 利用播送将标量与数组相加
c = a + b
print(c) # 输出:[3 4 5]
NumPy供给了很多聚合函数(如sum、mean、max、min等),可能对全部数组或指定轴上的元素停止聚合操纵。这些函数可能避免利用for轮返来一一元素停止打算。
import numpy as np
# 创建一个二维数组
a = np.array([[1, 2, 3], [4, 5, 6]])
# 对全部数组停止求跟
sum_a = np.sum(a)
print(sum_a) # 输出:21
# 按列求跟
sum_axis0 = np.sum(a, axis=0)
print(sum_axis0) # 输出:[5 7 9]
# 按行求跟
sum_axis1 = np.sum(a, axis=1)
print(sum_axis1) # 输出:[6 15]
NumExpr是一个对NumPy打算式停止的机能优化。NumExpr的利用及其简单,只须要将本来的NumPy语句利用双引号框起来,并利用numexpr中的evaluate方法挪用即可。
import numpy as np
import numexpr as ne
# 创建一个数组
a = np.linspace(0, 1000, 1000)
# NumPy打算
timeit_numpy = timeit.timeit('a**10', globals=globals(), number=10)
# NumExpr打算
timeit_numexpr = timeit.timeit('ne.evaluate("a**10")', globals=globals(), number=10)
print(f'NumPy打算时光:{timeit_numpy}')
print(f'NumExpr打算时光:{timeit_numexpr}')
Numba利用行业标准的LLVM编译器库在运转时将Python函数转换为优化的呆板代码。Python中Numba编译的数值算法可能濒临C或FORTRAN的速度。
from numba import jit
@jit(nopython=True)
def sum_array(arr):
return np.sum(arr)
# 创建一个数组
a = np.random.randint(0, 1000000, size=1000000)
# 利用Numba减速求跟
result = sum_array(a)
print(result)
经由过程以上实战代码实例剖析,我们可能看到NumPy在数据处理跟打算中存在宏大年夜的上风。经由过程优化NumPy代码,我们可能明显进步数据处理速度跟效力。在现实利用中,我们可能根据具体须要抉择合适的数据范例、向量化操纵、聚合函数以及机能优化东西,从而实现高效的NumPy数据处理。