简体   繁体   English

从列表中重塑numpy数组

[英]Reshaping numpy array from list

I have the following problem with shape of ndarray: 我对ndarray的形状存在以下问题:

out.shape = (20,)
reference.shape = (20,0)
norm = [out[i] / np.sum(out[i]) for i in range(len(out))]
# norm is a list now so I convert it to ndarray:
norm_array = np.array((norm))
norm_array.shape = (20,30)

# error: operands could not be broadcast together with shapes (20,30) (20,) 
diff = np.fabs(norm_array - reference)

How can I change shape of norm_array from (20,30) into (20,) or reference to (20,30), so I can substract them? 如何将norm_array的形状从(20,30)更改为(20,)或引用(20,30),以便减去它们?

EDIT: Can someone explain me, why they have different shape, if I can access both single elements with norm_array[0][0] and reference[0][0] ? 编辑:有人可以解释我,为什么它们具有不同的形状,如果我可以使用norm_array [0] [0]和reference [0] [0]访问两个单个元素?

I am not sure what you are trying to do exactly, but here is some information on numpy arrays. 我不确定您到底想做什么,但是这里有一些有关numpy数组的信息。

A 1-d numpy array is a row vector with a shape that is a single-valued tuple: 一维numpy数组是形状为单值元组的行向量:

>>> np.array([1,2,3]).shape
(3,) 

You can create multidimensional arrays by passing in nested lists. 您可以通过传递嵌套列表来创建多维数组。 Each sub-list is a 1-d row vector of length 1, and there are 3 of them. 每个子列表是长度为1的一维行向量,其中有3个。

>>> np.array([[1],[2],[3]]).shape
(3,1)

Here is the weird part. 这是奇怪的部分。 You can create the same array, but leave the lists empty. 您可以创建相同的数组,但将列表留空。 You end up with 3 row vectors of length 0. 您最终得到3个长度为0的行向量。

>>> np.array([[],[],[]]).shape
(3,0)

This is what you have for you reference array, an array with structure but no values. 这就是您要reference数组,它是具有结构但没有值的数组。 This brings me back to my original point: 这使我回到原来的观点:

You can't subtract an empty array. 您不能减去一个空数组。

If I make 2 arrays with the shapes you describe, I get an error 如果我用您描述的形状制作2个数组,则会出现错误

In [1856]: norm_array=np.ones((20,30))
In [1857]: reference=np.ones((20,0))
In [1858]: norm_array-reference
...
ValueError: operands could not be broadcast together with shapes (20,30) (20,0) 

But it's different from yours. 但这与您的不同。 But if I change the shape of reference , the error messages match. 但是,如果我更改reference的形状,则错误消息会匹配。

In [1859]: reference=np.ones((20,))
In [1860]: norm_array-reference
 ...
ValueError: operands could not be broadcast together with shapes (20,30) (20,) 

So your (20,0) is wrong. 因此,您的(20,0)是错误的。 I don't know if you mistyped something or not. 我不知道您是否输错了什么。

But if I make reference 2d with 1 in the last dimension, broadcasting works, producing a difference that matches (20,30) in shape: 但是,如果我在最后一个维度中用2 reference 2d,则广播工作正常,产生的差异与形状匹配(20,30):

In [1861]: reference=np.ones((20,1))
In [1862]: norm_array-reference

If reference = np.zeros((20,)) , then I could use reference[:,None] to add that singleton last dimension. 如果reference = np.zeros((20,)) ,那么我可以使用reference[:,None]添加该单例最后一个维度。

If reference is (20,), you can't do reference[0][0] . 如果reference为(20,),则不能执行reference[0][0] reference[0][0] only works with 2d arrays with at least 1 in the last dim. reference[0][0]仅适用于最后一个暗角中至少具有1的2d数组。 reference[0,0] is the preferred way of indexing a single element of a 2d array. reference[0,0]是索引2d数组单个元素的首选方法。

So far this is normal array dimensions and broadcasting; 到目前为止,这是正常的阵列尺寸和广播。 something you'll learn with use. 使用中会学到的东西。

=============== ===============

I'm puzzled about the shape of out . 我对out的形状感到困惑。 If it is (20,), how does norm_array end up as (20,30). 如果为(20,), norm_array结果如何为(20,30)。 out must consist of 20 arrays or lists, each of which has 30 elements. out必须包含20个数组或列表,每个数组或列表包含30个元素。

If out was 2d array, we could normalize without iteration 如果out是2d数组,我们可以进行标准化而无需迭代

In [1869]: out=np.arange(12).reshape(3,4)

with the list comprehension: 与列表理解:

In [1872]: [out[i]/np.sum(out[i]) for i in range(out.shape[0])]
Out[1872]: 
[array([ 0.        ,  0.16666667,  0.33333333,  0.5       ]),
 array([ 0.18181818,  0.22727273,  0.27272727,  0.31818182]),
 array([ 0.21052632,  0.23684211,  0.26315789,  0.28947368])]
In [1873]: np.array(_)   # and to array
Out[1873]: 
array([[ 0.        ,  0.16666667,  0.33333333,  0.5       ],
       [ 0.18181818,  0.22727273,  0.27272727,  0.31818182],
       [ 0.21052632,  0.23684211,  0.26315789,  0.28947368]])

Instead take row sums, and tell it to keep it 2d for ease of further use 取行总和,并告诉它保留2d以方便进一步使用

In [1876]: out.sum(axis=1,keepdims=True)
Out[1876]: 
array([[ 6],
       [22],
       [38]])

now divide 现在分裂

In [1877]: out/out.sum(axis=1,keepdims=True)
Out[1877]: 
array([[ 0.        ,  0.16666667,  0.33333333,  0.5       ],
       [ 0.18181818,  0.22727273,  0.27272727,  0.31818182],
       [ 0.21052632,  0.23684211,  0.26315789,  0.28947368]])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM