将数组的numpy数组或2D数组乘以向量的常用方法

时间:2019-02-25 14:19:27

标签: python arrays numpy

我想得到一个结果 ax = as_x-aseg_3d * aline_a

其中as_x和aline_a是numpy向量,而aseg_3d是数组的数组。 as_x.shape和aline_a形状为(S,),aseg_3d形状也显示为(S,),因为它应该用于数组数组。结果ax也是形状与aseg_3d相同的数组的数组。

问题在于,aseg_3d是一个数组数组,因为其中的数组具有不同的长度。但是,有时它们不是,而aseg_3d只是2D数组。然后,上面的复数操作在ValueError上失败:操作数不能与形状(S,N)一起广播。

我可以通过以下方法解决此问题: ax = as_x [:,None] -aseg_3d * aline_a [:,None]

但是当我有一个数组数组时,这与前面的情况不一样。

有没有办法使它在两种情况下都能工作:数组数组和2D数组?

或者也许有一种方法可以使所有内部数组具有相同长度的numpy数组dtype =“ object”保持不变?

顺便说一句。我正尝试使用列表推导进行上述乘法,该方法始终可以工作,但速度慢得多。

感谢您的所有建议!

1 个答案:

答案 0 :(得分:0)

在两种情况下均有效的表达方式:

您可以利用移调。简单的情况(只是乘法):

(vector * vec_of_vecs_or_2D.T).T

完整OP示例:

(vector1 - vector2 * vec_of_vecs_or_2D.T).T

示例:

>>> v = np.array([3, 5])
>>> A = np.array((*map(np.array,[[1,2],[1,2,3]]),))
>>> B = np.array([[1,2,4],[1,2,3]])
>>> 
>>> v
array([3, 5])
>>> A
array([array([1, 2]), array([1, 2, 3])], dtype=object)
>>> B
array([[1, 2, 4],
       [1, 2, 3]])
>>> 
>>> (v*B.T).T
array([[ 3,  6, 12],
       [ 5, 10, 15]])
>>> (v*A.T).T
array([array([3, 6]), array([ 5, 10, 15])], dtype=object)

工作方式:

如果vec_of_vecs_or_2D是对象dtype的一维,则转置不执行任何操作。

如果vec_of_vecs_or_2D是真正的2D,则转置将与vector匹配的轴移到末尾,因此vector被正确广播,然后又返回。

为什么便宜:

请注意,numpy中的转置是惰性的。它实际上并不移动任何数据,而只是“交换轴标签”。

例如,在笔记本电脑上进行1000x1000阵列的转置大约需要200 ns:

>>> a = np.arange(1_000_000).reshape(1000, 1000)
>>> timeit(lambda: a.T)
0.22008929261937737

或者,在任何情况下都强制使用数组:

示例

>>> L1 = [np.arange(i, 2*i+2) for i in range(3)]
>>> L2 = [np.arange(i, i+3) for i in range(3)]
>>> L1
[array([0, 1]), array([1, 2, 3]), array([2, 3, 4, 5])]
>>> L2
[array([0, 1, 2]), array([1, 2, 3]), array([2, 3, 4])]

方法1(难看但简单):

>>> A1 = np.array([*L1, None])[:-1]
>>> A2 = np.array([*L2, None])[:-1]
>>> A1
array([array([0, 1]), array([1, 2, 3]), array([2, 3, 4, 5])], dtype=object)
>>> A2
array([array([0, 1, 2]), array([1, 2, 3]), array([2, 3, 4])], dtype=object)

方法2 :(虽然不那么难看但很复杂)

>>> A1 = np.frompyfunc(L1.__getitem__, 1, 1)(range(len(L1)))
>>> A2 = np.frompyfunc(L2.__getitem__, 1, 1)(range(len(L2)))
>>> A1
array([array([0, 1]), array([1, 2, 3]), array([2, 3, 4, 5])], dtype=object)
>>> A2
array([array([0, 1, 2]), array([1, 2, 3]), array([2, 3, 4])], dtype=object)