1

以下代码不会生成我想要的;要将元组中的每个元组转换为 Numpy 数组,因此可以选择检索具有多个索引的值。

import numpy as np
a=np.asarray([[1,2,3],[2,3,4,5]])
print a

输出是错误:

IndexError: too many indices 

但是我希望它检索的是 1,因为第一个元组第一个元组第一个值是一个。我应该如何进行这样的转换?

更新: 有趣的是,当我尝试类似:

a=np.asarray([np.asarray([1,2,3]),np.asarray([2,3,4,5])])
b=np.asarray([np.asarray([1,2,3]),np.asarray([2,3,4,5])])
print np.multiply(a,b)

这会产生所需的输出!这是逐个元素的乘法。

[array([1, 4, 9]) array([ 4,  9, 16, 25])]
4

2 回答 2

3

您不能将示例直接转换为 NumPy 数组,因为您的长度不同。您得到的结果是一个包含 Python 列表对象的一维 NumPy 数组。我已经看到您尝试做的事情被称为锯齿状数组,但不确定这是否是任何官方术语。

您可以用零填充元素或使用稀疏矩阵,或者干脆不转换为 NumPy。取决于你的总体目标。

为了让您开始,您可以从锯齿状数组中设置屏蔽数组并计算沿轴的总和。比我更多地使用这个模块的人可能会提出更有效或更惯用的建议:

>>> a = np.array([[[1,2,3],[2,3,4,5], [2, 2]],[[3,4,5,6,7],[1],[2,3,10]]])
>>> D = max(len(x) for x in y for y in a)
>>> padded = [[x + [0] * (D-len(x)) for x in y] for y in a]
>>> mask = [[[0] * len(x) + [1] * (D-len(x)) for x in y] for y in a]
>>> result = np.ma.masked_array(padded, np.array(mask, dtype=np.bool))
>>> result
masked_array(data =
 [[[1 2 3 -- --]
  [2 3 4 5 --]
  [2 2 -- -- --]]

 [[3 4 5 6 7]
  [1 -- -- -- --]
  [2 3 10 -- --]]],
             mask =
 [[[False False False  True  True]
  [False False False False  True]
  [False False  True  True  True]]

 [[False False False False False]
  [False  True  True  True  True]
  [False False False  True  True]]],
       fill_value = 999999)

>>> np.sum(result, axis=-1)
masked_array(data =
 [[6 14 4]
 [25 1 15]],
             mask =
 [[False False False]
 [False False False]],
       fill_value = 999999)

>>> 
于 2013-11-03T18:19:43.223 回答
0

如果我改变你的ab那么 numpy 会创建一个二维数组,而不是数组数组:

In [5]: am=np.asarray([np.asarray([1,2,3,0]),np.asarray([2,3,4,5])])
#array([[1, 2, 3, 0],
#       [2, 3, 4, 5]])
In [7]: bm=np.asarray([np.asarray([1,2,3,0]),np.asarray([2,3,4,5])])

并做计时:

In [10]: timeit np.multiply(a,b)
100000 loops, best of 3: 7.94 us per loop

In [11]: timeit np.multiply(am,bm)
100000 loops, best of 3: 1.89 us per loop

纯ndarray乘法要快得多。在一种情况下,它可以直接跳到逐元素乘法(在快速C代码级别);另一方面,它进行通用迭代,使用对象而不是简单的数字。它正在做一些接近 Python 迭代的事情。

事实上,如果我明确地执行那个循环,我会得到接近那个更长的时间

al,bl=a.tolist(), b.tolist()
In [21]: timeit np.array([np.multiply(x,y) for x,y in zip(al,bl)])
100000 loops, best of 3: 8.99 us per loop

现在让我们看看你的“最后一个维度的总和”问题。首先请注意,sum(or add.reduce) 尚未扩展为使用这种类型的数组。

In [37]: timeit am.sum(axis=1)
100000 loops, best of 3: 11.5 us per loop

In [38]: timeit [x.sum() for x in a]
10000 loops, best of 3: 21.5 us per loop

的速度优势ndarray sum没有那么大。 可以通过将其编码为产品(使用or )sum来加速:dotnp.doteinsum

In [42]: timeit np.einsum('ij->i',am)
100000 loops, best of 3: 4.79 us per loop

In [50]: ones=np.array([1,1,1,1])
In [51]: timeit np.dot(am,ones)
100000 loops, best of 3: 2.37 us per loop

In [55]: timeit [np.einsum('j->',x) for x in a]
100000 loops, best of 3: 12.3 us per loop

In [64]: c=np.asarray([np.asarray([1,1,1]),np.asarray([1,1,1,1])])   
In [65]: timeit [np.dot(x,y) for x,y in zip(a,c)]
100000 loops, best of 3: 8.12 us per loop

因此,虽然可以构造不规则数组(或数组数组),但它们与数组列表相比并没有显着的速度优势。通常,快速numpy数组操作不适用于作为通用 Python 对象 ( dtype=object) 的元素。

于 2013-11-03T21:04:17.920 回答