【问题标题】:How to create a Numpy Matrix with a for loop?如何使用 for 循环创建 Numpy 矩阵?
【发布时间】:2019-08-18 19:10:18
【问题描述】:

我正在尝试使用一个名为噪声的随机数数组构建一个带有 numpy 的矩阵,该数组具有 4 个值,应该乘以一个名为“因子”的数组中的 8 个不同数字,从而在最终矩阵中产生 8 行。

因此,“噪声”中的每个值的矩阵应该有 4 列,每个因子应该有 8 行。 我不知道如何实现。

这是我得到的代码:

import numpy as np  
from numpy import random

n = 4
noise = np.random.normal(size=n)


matrix = np.zeros((8,n)) # Pre-allocate matrix
for i in range(1,8):
   matrix[:,i] = [[noise]*i]


print(matrix)

我收到错误消息:


ValueError: setting an array element with a sequence.

【问题讨论】:

  • 所以 matrix 是 (8,n) 和 matrix[:,i] 是 (n,) 形状。 noise 是 (n,) 形状。但是[[noise]*i] 的形状是什么。它其实是一个列表,但是当变成一个数组时,它是什么?

标签: python arrays loops numpy matrix


【解决方案1】:

您要构建的是外层产品

n = 4
noise = np.random.normal(size=n)
noise
# array([ 2.39723122, -0.99797246, -0.14242618, -0.55921136])

m = 8
factor = np.random.randint(0,10,m)
factor
# array([0, 5, 7, 6, 7, 3, 8, 6])

np.outer(factor,noise)
# array([[ 0.        , -0.        , -0.        , -0.        ],
#        [11.98615612, -4.98986228, -0.71213089, -2.79605682],
#        [16.78061856, -6.98580719, -0.99698324, -3.91447955],
#        [14.38338734, -5.98783473, -0.85455707, -3.35526818],
#        [16.78061856, -6.98580719, -0.99698324, -3.91447955],
#        [ 7.19169367, -2.99391737, -0.42727853, -1.67763409],
#        [19.17784979, -7.98377964, -1.13940942, -4.47369091],
#        [14.38338734, -5.98783473, -0.85455707, -3.35526818]])

许多二进制 ufunc 都存在“外部”操作。因为外乘

np.multiply.outer(factor,noise)

很常见,它有自己的功能outer

外部运算(对于乘法或其他 ufuncs)大致相当于(对于一维操作数)

np.multiply(*np.ix_(factor,noise))

如果存在减少形式(prod 表示乘法,sum 表示加法,min 表示最小值等),我们也可以这样写

np.prod(np.ix_(factor,noise))

最后,(有点不相关)在产品的情况下我们也可以使用einsum

np.einsum('i,j',factor,noise)

虽然einsum 对于这个问题来说可能是矫枉过正。

【讨论】:

    【解决方案2】:

    你可以这样做而不是使用循环:

    matrix = np.random.normal(size=(1, n)) * np.arange(8).reshape(-1, 1)
    

    这里,乘法的左边是(1, n),而右边是(8, 1)。所以它们都将被广播到形状(8, n),然后执行逐元素乘法。

    【讨论】:

      【解决方案3】:
      In [12]: n = 4 
          ...: noise = np.random.normal(size=n)                                                                    
      In [13]: noise                                                                                               
      Out[13]: array([-1.93374989, -1.16536624,  0.42338714, -2.39942219])
      

      让我们看看您要分配的内容 - 对于特定的i

      In [14]: np.array([[noise]*1])                                                                               
      Out[14]: array([[[-1.93374989, -1.16536624,  0.42338714, -2.39942219]]])
      In [15]: np.array([[noise]*2])                                                                               
      Out[15]: 
      array([[[-1.93374989, -1.16536624,  0.42338714, -2.39942219],
              [-1.93374989, -1.16536624,  0.42338714, -2.39942219]]])
      In [16]: np.array([[noise]*3])                                                                               
      Out[16]: 
      array([[[-1.93374989, -1.16536624,  0.42338714, -2.39942219],
              [-1.93374989, -1.16536624,  0.42338714, -2.39942219],
              [-1.93374989, -1.16536624,  0.42338714, -2.39942219]]])
      

      您正在将*3 应用于列表 - 这意味着“复制”:

      In [17]: [[noise]*3]                                                                                         
      Out[17]: 
      [[array([-1.93374989, -1.16536624,  0.42338714, -2.39942219]),
        array([-1.93374989, -1.16536624,  0.42338714, -2.39942219]),
        array([-1.93374989, -1.16536624,  0.42338714, -2.39942219])]]
      

      形状有 (1,1,4), (1,2,4), (1,3,4) 等。Python 中的括号创建一个列表;不要随便使用它们。但是

      In [21]: np.zeros((8,4))[:,1].shape                                                                          
      Out[21]: (8,)
      

      您试图将每个都放入一个大小为 (8,) 的插槽中。

      您是否想将noise 的值乘以i

      matrix = np.zeros((8,n)) # Pre-allocate matrix
      for i in range(8):
         matrix[i,:] = noise*i
      

      应该可以正常工作,将matrix[i,:] 插槽与源noise 正确匹配。

      【讨论】:

      • 非常感谢您的帮助。如果 i 的值不在 (0,8) 范围内但也来自具有随机数的数组,我该怎么办。以下不起作用:python noise_fac = np.array([0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8]) b = 0.66 noise = rice.rvs(b, size=n) matrix = np.zeros((8,n)) # Pre-allocate matrix for i in (noise_fac): matrix[i,:] = noise*i print(matrix)
      • 在评论中阅读代码并不容易。你不能像matrix 那样索引noise_fac 吗?还是改写@GZ0 的答案?
      猜你喜欢
      • 1970-01-01
      • 2018-11-04
      • 1970-01-01
      • 2015-06-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-25
      • 2022-01-09
      相关资源
      最近更新 更多