从一维阵列高效构建二维阵列

2024-09-30 22:14:13 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在用numpy(python2.7)从1d数组构建2d数组。我在寻找最有效的方法。最新的发现是:

a=np.ones(100000)

#   SUBSCRIPTING

n_dim=3
x=0

for i in xrange(0,1000):
    x=np.zeros(shape=(100000,n_dim))
    for j in xrange(0,n_dim):
        x[:,j]=a*j

# ~1.574 s/1000 loops - joinind 3 1d arrays
# ~9.162 s/1000 loops - joinind 10 1d arrays



#   STACKING

for i in xrange(0,1000):
    x=a*0.
    for j in xrange(1,n_dim):
        x=np.vstack((x,a*j))
    x=x.T

# ~1.786 s/1000 loops - joinind 3 1d arrays
# ~16.603 s/1000 loops - joinind 10 1d arrays

第一种方法(下标)是我想出的最快的方法,与第二种方法(叠加)相比,性能的提高随着我加入的一维数组的数量而增加。由于我需要重复这一步,我想知道是否有更快的方法?如果解决方案提供了显著的性能提升,那么我愿意使用这种方案。在

也许我可以尝试以一种限制堆叠操作次数的方式堆叠阵列(例如,将4个1d阵列连接起来:首先堆叠阵列1和2,然后堆叠阵列3和4,最后再堆叠结果阵列)。在

我的问题是如何从一维阵列高效地构建二维阵列。我在这里使用的数组中的值是虚拟的。在实际应用程序中,我加入的一维数组中的大多数值可能会有所不同。在


Tags: 方法innumpyfornponeszeros数组
2条回答

因为numpy将数组(默认情况下)存储在row-major order中,按行设置值更有效。因此,我将使用:

x=np.zeros(shape=(n_dim, 100000))
for j in range(0,n_dim):
    x[j,:]=a*j

或者,您可以将x定义为列major,然后,这与前面的代码一样快:

^{pr2}$

您还可以使用numpy外部产品创建x

v = np.arange(n_dim)
x = np.outer(v, a)

这是使用vstack的糟糕方法;您反复调用它,为每个j创建一个新的x

x=a*0.
for j in xrange(1,n_dim):
    x=np.vstack((x,a*j))
x=x.T

正确的方法是构建一个数组列表,并且只使用vstack一次。在

^{pr2}$

在这种情况下,appendvstack一样工作,可能更快。还有一个column_stack函数。关键的区别是我利用了快速列表追加,以及array(和vstack)在其参数列表中获取许多项的能力。在

如果你能把循环写成一个列表理解,那就更好了

x = np.array([a*j for j in xrange(1,n_dim)])

在预先分配的数组中插入通常是最快的选择。但是您应该熟悉这种从列表构建的方法。在

基本np.array表达式

np.array([[1,2,3],[4,5,6]])

就是这样,从1d数组的列表(或者在本例中是列表)构建2d。在

np.array([a*0,a*1,a*2])

jakub注意到{}速度很慢。对于n_dim=10

In [257]: timeit x=np.array([(a*j) for j in range(n_dim)]).T
1 loops, best of 3: 228 ms per loop

In [258]: timeit x=np.array([(a*j).tolist() for j in range(n_dim)]).T
1 loops, best of 3: 228 ms per loop

显然,np.array正在将输入数组转换为列表,然后从嵌套列表(或类似的东西)中执行其通常的构造。在

In [259]: timeit x=np.vstack([(a*j) for j in range(n_dim)]).T
10 loops, best of 3: 24.9 ms per loop

数组列表上的vstack要快得多。比迭代的vstack(我预期的)快。基本上与Ramon's行插入(和插入order='F')相同

In [272]: %%timeit
x=np.zeros((n_dim,a.shape[0]))
for j in range(n_dim):
   x[j,:]=a*j
   .....: x=x.T
   .....: 
10 loops, best of 3: 23.3 ms per loop

concatenate(由vstack使用)被编译时,我怀疑它做了类似于迭代插入的操作。在源代码中,通常创建一个空的目标数组,然后用适当的值填充它。在

相关问题 更多 >