如何有效地创建一个多维numpy数组,其条目仅取决于一维索引?
如何使用内置函数更有效地创建下列numpy数组?如何有效地创建一个多维numpy数组,其条目仅取决于一维索引?
import numpy as np
MyArray = np.zeros([10,10,10,10,10])
for i in range(10):
for j in range(10):
for k in range(10):
for l in range(10):
for m in range(10):
MyArray[i,j,k,l,m] = l
正如你所看到的,元素只应该依赖于一个维度指数。我尝试使用numpy.tile
,但到目前为止还不能确定。
看来你np.broadcast_to
后:
# build an array where l_vals[0,0,0,i,0] = i
l_vals = np.arange(10).reshape(1, 1, 1, -1, 1)
# duplicate that array, without copies, in the other axes
l_grid = np.broadcast_to(l_vals, (10, 10, 10, 10, 10))
值得一提的是,broadcast_to
返回一个只读数组,因为元素实际上共享内存位置。如果你想创建后写入到这一点,那么你可以调用np.copy
,或使用tile
代替:
l_grid = np.tile(l_vals, (10, 10, 10, 1, 10))
你也只是具有扁平您的循环:
MyArray = np.zeros([10,10,10,10,10])
for l in range(10):
MyArray[:,:,:,l,:] = l
尝试np.fromfunction,你的情况这将是类似的东西: MyArray = np.fromfunction(lambda i, j, k, l, m : l, (10, 10, 10, 10, 10))
小的浪费,但做这项工作 – Eric
你可以这样做一个循环:
import numpy as np
MyArray = np.zeros([10,10,10,10,10])
for l in range(10):
MyArray[:, :, :, l, :] = l
很明显,你也可以做到这一点作为一个列表理解。
对我来说,这看起来似乎不像列表理解的形式... – Eric
是的,对不起,似乎我的手指在键盘上速度比我的大脑可以跟上:) –
下面是与initialization
的方法 -
n = 10
a = np.empty((n,n,n,n,n),dtype=int)
a[...] = np.arange(n)[:,None]
这里还有一个NumPy strides
基础的方法 -
r = np.arange(n)
s = r.strides[0]
shp = (n,n,n,n,n)
out = np.lib.index_tricks.as_strided(r, shape=shp, strides=(0,0,0,s,0))
运行测试
途径 -
# @Eric's soln1
def broadcast_to_based(n): # Creates a read-only array
l_vals = np.arange(n).reshape(1, 1, 1, -1, 1)
return np.broadcast_to(l_vals, (n, n, n, n, n))
# @Eric's soln2
def tile_based(n):
l_vals = np.arange(n).reshape(1, 1, 1, -1, 1)
return np.tile(l_vals, (n, n, n, 1, n))
# @kmichael08's soln
def fromfunc_based(n):
return np.fromfunction(lambda i, j, k, l, m : l, (n, n, n, n, n))
# @Tw UxTLi51Nus's soln
def loop_based(n):
MyArray = np.zeros([n,n,n,n,n],dtype=int)
for l in range(n):
MyArray[:, :, :, l, :] = l
return MyArray
# Proposed-1 in this post
def initialization_based(n):
a = np.empty((n,n,n,n,n),dtype=int)
a[...] = np.arange(n)[:,None]
return a
# Proposed-2 in this post
def strided_based(n):
r = np.arange(n)
s = r.strides[0]
shp = (n,n,n,n,n)
return np.lib.index_tricks.as_strided(r, shape=shp, strides=(0,0,0,s,0))
个
计时 -
In [153]: n = 10
...: %timeit broadcast_to_based(n)
...: %timeit tile_based(n)
...: %timeit fromfunc_based(n)
...: %timeit loop_based(n)
...: %timeit initialization_based(n)
...: %timeit strided_based(n)
...:
100000 loops, best of 3: 4.1 µs per loop
1000 loops, best of 3: 236 µs per loop
1000 loops, best of 3: 645 µs per loop
10000 loops, best of 3: 180 µs per loop
10000 loops, best of 3: 89.1 µs per loop
100000 loops, best of 3: 5.44 µs per loop
In [154]: n = 20
...: %timeit broadcast_to_based(n)
...: %timeit tile_based(n)
...: %timeit fromfunc_based(n)
...: %timeit loop_based(n)
...: %timeit initialization_based(n)
...: %timeit strided_based(n)
...:
100000 loops, best of 3: 4.05 µs per loop
100 loops, best of 3: 8.16 ms per loop
10 loops, best of 3: 24.1 ms per loop
100 loops, best of 3: 6.07 ms per loop
100 loops, best of 3: 2.31 ms per loop
100000 loops, best of 3: 5.48 µs per loop
值得一提的是'np.broadcast_to'创建了一个只读数组。 – Divakar