矢量化 "is in"
Vectorize "is in"
我尝试构建 m
个向量样本(带有整数条目)以及 m
个评估。如果其中一个条目是数字 2
,则形状 (n,1)
的向量 x
的计算结果为 y=1
。否则,它被评估为 y=0
.
为了处理许多这样的向量和评估,样本向量存储在 (n,m)
形 ndarray
中,评估存储在 (1,m)
形 ndarray
中。见代码:
import numpy as np
n = 10 # number of entries in each sample vector
m = 1000 # number of samples
X = np.random.randint(-10, 10, (n, m))
Y = []
for i in range(m):
if 2 in X[:, i]:
Y.append(1)
else:
Y.append(0)
Y = np.array(Y).reshape((1,-1))
assert (Y.shape == (1,m))
如何向量化 Y
的计算?我尝试用以下内容替换 X
和 Y
的 initialization/computation:
X = np.random.randint(-10,10,(n,m))
Y = np.apply_along_axis(func1d=lambda x: 1 if 2 in x else 0, axis=0, arr=X)
一些执行表明这在大多数情况下甚至比我的第一种方法慢一点。 (实际上 this anser 首先说 numpy.apply_along_axis
不是为了速度。我也不知道 lambda
在这种情况下有多好。)
有没有办法对 Y
的计算进行矢量化,即根据该列是否包含元素,为每一列分配值 1
或 0
的方法2
?
当使用 Numpy 数组和逻辑语句时,它会进行大量优化,而无需用户手动矢量化任务。以下代码达到相同的解决方案:
# assign logical 1 where element == 2 everywhere in the array X,
# then, for each column (axis = 0), if any element == 1 assign column logical 1
Y = (X == 2).any(axis = 0).reshape(1, -1)
print(Y.shape)
使用 timeit 评估执行时间:
循环方法:每个 运行
3240 微秒
numpy 方法:每 运行
6.57 微秒
如果您有兴趣,您可以看看是否使用其他矢量化方法(例如 np.vectorise)可以进一步缩短时间,尽管我很确定底层 Numpy 优化在 [=31] 执行它们自己的矢量化=] 默认指令级 (SIMD)。
底线是在使用 numpy 时始终尝试使用逻辑数组和 numpy functions/methods 找到解决方案,因为它们已经在编译的二进制文件中进行了高度优化,并且任何 python 函数用于操作、访问或迭代数据会显着降低执行速度。
顺便说一句,要加快 for 循环执行速度以构建输出列表(如您所做的那样)的最常见方法是使用列表理解:
Y = np.array([2 in X[:, i] for i in range(m)]).reshape((1, -1))
每个循环执行 3070 微秒。
我尝试构建 m
个向量样本(带有整数条目)以及 m
个评估。如果其中一个条目是数字 2
,则形状 (n,1)
的向量 x
的计算结果为 y=1
。否则,它被评估为 y=0
.
为了处理许多这样的向量和评估,样本向量存储在 (n,m)
形 ndarray
中,评估存储在 (1,m)
形 ndarray
中。见代码:
import numpy as np
n = 10 # number of entries in each sample vector
m = 1000 # number of samples
X = np.random.randint(-10, 10, (n, m))
Y = []
for i in range(m):
if 2 in X[:, i]:
Y.append(1)
else:
Y.append(0)
Y = np.array(Y).reshape((1,-1))
assert (Y.shape == (1,m))
如何向量化 Y
的计算?我尝试用以下内容替换 X
和 Y
的 initialization/computation:
X = np.random.randint(-10,10,(n,m))
Y = np.apply_along_axis(func1d=lambda x: 1 if 2 in x else 0, axis=0, arr=X)
一些执行表明这在大多数情况下甚至比我的第一种方法慢一点。 (实际上 this anser 首先说 numpy.apply_along_axis
不是为了速度。我也不知道 lambda
在这种情况下有多好。)
有没有办法对 Y
的计算进行矢量化,即根据该列是否包含元素,为每一列分配值 1
或 0
的方法2
?
当使用 Numpy 数组和逻辑语句时,它会进行大量优化,而无需用户手动矢量化任务。以下代码达到相同的解决方案:
# assign logical 1 where element == 2 everywhere in the array X,
# then, for each column (axis = 0), if any element == 1 assign column logical 1
Y = (X == 2).any(axis = 0).reshape(1, -1)
print(Y.shape)
使用 timeit 评估执行时间:
循环方法:每个 运行
3240 微秒numpy 方法:每 运行
6.57 微秒如果您有兴趣,您可以看看是否使用其他矢量化方法(例如 np.vectorise)可以进一步缩短时间,尽管我很确定底层 Numpy 优化在 [=31] 执行它们自己的矢量化=] 默认指令级 (SIMD)。
底线是在使用 numpy 时始终尝试使用逻辑数组和 numpy functions/methods 找到解决方案,因为它们已经在编译的二进制文件中进行了高度优化,并且任何 python 函数用于操作、访问或迭代数据会显着降低执行速度。
顺便说一句,要加快 for 循环执行速度以构建输出列表(如您所做的那样)的最常见方法是使用列表理解:
Y = np.array([2 in X[:, i] for i in range(m)]).reshape((1, -1))
每个循环执行 3070 微秒。