具有多个维度的numpy数组的列表理解式方法

时间:2014-10-01 17:20:49

标签: python arrays numpy list-comprehension

我有一个相同高度但不是宽度的2d numpy数组列表:

list_of_arrays = [np.random.rand(3,4),np.random.rand(3,5),np.random.rand(3,6)]

我想构建一个新数组,其中每列是列表中数组的随机列。我可以使用for循环执行此操作,例如:

new_array = np.zeros((3,3))
for x in range(3):
    new_array[:,x] = list_of_arrays[x][:,random.randint(0,list_of_arrays[x].shape[1])]

这对我来说并不干净。我想使用类似列表理解的方法,例如

new_array = [list_of_arrays[x][:,random.randint(0,list_of_arrays[x].shape[1])] for x in range(3)]

显然会返回一个列表,而不是所需的数组。我可以将列表转换为数组,但这会添加一个无关的中间数。有一个简单的方法吗?我在使用1d数组时看到的类似问题使用的是numpy.fromiter,但这在2维中不起作用。

如果有人想提出完全不同/更清洁/更有效的方法来解决这个问题,那也是值得赞赏的。

2 个答案:

答案 0 :(得分:2)

通过迭代数组而不是索引

,可以使列表理解更简单
new_array = np.array([x[:,np.random.randint(0, x.shape[1])] for x in list_of_arrays]).T

In [32]: %timeit np.array([x[:,np.random.randint(0, x.shape[1])] for x in a]).T
100000 loops, best of 3: 10.2 us per loop

转置(.T)是因为遍历数组会产生行,因此遍历arr.T会产生列。同样,在构造数组时,每个元素都被认为是一行,因此在构造之后,我们需要对它进行转置,以便将我们提供给数组结构的列表转换为列。

如果您导入标准random模块,则可以执行

new_array = np.array([random.choice(x.T) for x in list_of_arrays]).T

In [36]: %timeit np.array([random.choice(x.T) for x in a]).T
100000 loops, best of 3: 9.18 us per loop

稍快一些。

答案 1 :(得分:0)

您可以将数组合并到另一个数组而不是列表中吗?

>>> b= np.hstack((np.random.rand(3,4),np.random.rand(3,5),np.random.rand(3,6)))
>>> b.shape
(3, 15)

然后你可以使用broadcasting而不是列表理解来选择随机列:

new_array=b[:,np.random.randint(0,b.shape[1],3)]