使用NumPy优于Python列表的优势

In this article, I will show a few neat tricks that come with NumPy, yet are must faster than vanilla python code.

在本文中,我将展示NumPy附带的一些巧妙技巧,但必须比普通python代码更快。

内存使用情况 (Memory usage)

The most important gain is the memory usage. This comes in handy when we implement complex algorithms and in research work.

最重要的收益是内存使用率。 当我们实现复杂的算法和进行研究工作时,这将派上用场。

array = list(range(10**7))
np_array = np.array(array)

I found the following code from a blog. I will be using this code snippet to compute the size of the objects in this article.

从博客中找到了以下代码。 在本文中,我将使用此代码段计算对象的大小。

get_size(array) ====> 370000108 bytes ~ 352.85MB
get_size(np_array) => 80000160 bytes ~ 76.29MB

This is because NumPy arrays are fixed-length arrays, while vanilla python has lists that are extensible.

这是因为NumPy数组是定长数组,而vanilla python具有可扩展的列表。

速度 (Speed)

Speed is, in fact, a very important property in data structures. Why does it take much less time to use NumPy operations over vanilla python? Let’s have a look at a few examples.

实际上,速度是数据结构中非常重要的属性。 为什么在香草python上使用NumPy操作需要更少的时间? 让我们看几个例子。

矩阵乘法 (Matrix Multiplication)

In this example, we will look at a scenario where we multiply two square matrices.

在此示例中,我们将研究将两个平方矩阵相乘的情况。

from time import time
import numpy as npdef matmul(A, B):
N = len(A)
product = [[0 for x in range(N)] for y in range(N)] for i in range(N):
for j in range(N):
for k in range(N):
product[i][j] += matrix1[i][k] * matrix2[k][j]
return productmatrix1 = np.random.rand(1000, 1000)
matrix2 = np.random.rand(1000, 1000)t = time()
prod = matmul(matrix1, matrix1)
print("Normal", time() - t)
t = time()
np_prod = np.matmul(matrix1, matrix2)
print("Numpy", time() - t)

The times will be observed as follows;

时间将被观察如下。

Normal 7.604596138000488
Numpy 0.0007512569427490234

We can see that the NumPy implementation is almost 10,000 times faster. Why? Because NumPy uses under-the-hood optimizations such as transposing and chunked multiplications. Furthermore, the operations are vectorized so that the looped operations are performed much faster. The NumPy library uses the BLAS (Basic Linear Algebra Subroutines) library under in its backend. Hence, it is important to install NumPy properly to compile the binaries to fit the hardware architecture.

我们可以看到NumPy的实现快了将近10,000倍。 为什么? 因为NumPy使用了底层优化,例如转置和分块乘法。 此外,将操作向量化,以便更快地执行循环操作。 NumPy库在其后端使用BLAS(基本线性代数子例程)库。 因此,正确安装NumPy以编译二进制文件以适合硬件体系结构非常重要。

更多矢量化操作 (More Vectorized Operations)

Vectorized operations are simply scenarios that we run operations on vectors including dot product, transpose and other matrix operations, on the entire array at once. Let’s have a look at the following example that we compute the element-wise product.

向量化运算只是简单的场景,我们可以在整个阵列上一次对向量执行运算,包括点积,转置和其他矩阵运算。 让我们看一下下面的示例,我们将计算按元素乘积。

vec_1 = np.random.rand(5000000)
vec_2 = np.random.rand(5000000)t = time()
dot = [float(x*y) for x, y in zip(vec_1, vec_2)]
print("Normal", time() - t)
t = time()
np_dot = vec_1 * vec_2
print("Numpy", time() - t)

The timings on each operation will be;

每个操作的时间将是;

Normal 2.0582966804504395
Numpy 0.02198004722595215

We can see that the implementation of NumPy gives a much faster vectorized operation.

我们可以看到NumPy的实现提供了更快的向量化操作。

广播业务 (Broadcast Operations)

Numpy vectorized operations also provide much faster operations on arrays. These are called broadcast operations. This is because the operations are broadcasted over the entire array using Intel Vectorized instructions (Intel AVX).

Numpy向量化操作还提供了对阵列更快的操作。 这些称为广播操作 。 这是因为操作是使用Intel向量化指令( Intel AVX )在整个阵列上广播的。

vec = np.random.rand(5000000)t = time()
mul = [float(x) * 5 for x in vec]
print("Normal", time() - t)
t = time()
np_mul = 5 * vec
print("Numpy", time() - t)

Let’s see how the running times look;

让我们看看运行时间如何。

Normal 1.3156049251556396
Numpy 0.01950979232788086

Almost 100 times!

差不多100次!

筛选 (Filtering)

Filtering includes scenarios where you only pick a few items from an array, based on a condition. This is integrated into the NumPy indexed access. Let me show you a simple practical example.

筛选包括根据条件仅从阵列中选择一些项目的方案。 这已集成到NumPy索引访问中。 让我向您展示一个简单的实际示例。

X = np.array(DATA)
Y = np.array(LABELS)Y_red = Y[Y=='red'] # obtain all Y values with RED
X_red = X[Y=='red'] # feed Y=='red' indices and filter X

Let’s compare this against the vanilla python implementation.

让我们将其与香草python实现进行比较。

X = np.random.rand(5000000)
Y = np.int64(10 * np.random.rand(5000000))t = time()
Y_even = [int(y) for y in Y if y%2==0]
X_even = [float(X[i]) for i, y in enumerate(Y) if y%2==0]
print("Normal", time() - t)
t = time()
np_Y_even = Y[Y%2==0]
np_X_even = X[Y%2==0]
print("Numpy", time() - t)

The running times are as follows;

运行时间如下:

Normal 6.341982841491699
Numpy 0.2538008689880371

This is a pretty handy trick when you want to separate data based on some condition or the label. It is very useful in data analytics and machine learning.

当您要根据某些条件或标签分离数据时,这是一个非常方便的技巧。 它在数据分析和机器学习中非常有用。

Finally, let’s have a look at np.where which enables you to transform a NumPy array with a condition.

最后,让我们看一下np.where ,它使您能够转换带条件的NumPy数组。

X = np.int64(10 * np.random.rand(5000000))
X_even_or_zeros = np.where(X%2==0, 1, 0)

This returns an array where even-numbered slots are replaced with ones and others with zeros.

这将返回一个数组,其中偶数编号的插槽将替换为1,而其他编号的插槽将替换为零。

These are a few vital operations and I hope the read was worth the time. I always use NumPy with huge numeric datasets and find the performance very satisfying. NumPy has really helped the research community to stick with python without levelling down to C/C++ to gain numeric computation speeds. Room for improvements still exists!

这些是一些至关重要的操作,我希望阅读是值得的。 我始终将NumPy与庞大的数字数据集结合使用,并发现性能非常令人满意。 NumPy确实帮助研究社区坚持使用python,而无需降低到C / C ++来获得数值计算速度。 仍有改进的空间!

Cheers!

干杯!

翻译自: https://medium.com/swlh/why-use-numpy-d06c573fbcda

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值