【问题标题】:Dealing with multi-dimensional arrays when ndims not known in advance事先不知道 ndim 时处理多维数组
【发布时间】:2013-11-10 12:13:16
【问题描述】:

我正在处理来自 netcdf 文件的数据,以及多维变量,读入 numpy 数组。我需要扫描所有维度的所有值(numpy 中的轴)并更改一些值。但是,我事先不知道任何给定变量的维度。在运行时,我当然可以获取 numpy 数组的 ndim 和形状。 如何在不事先知道维度数或形状的情况下对所有值进行循环编程?如果我知道一个变量正好是二维的,我会这样做

shp=myarray.shape
for i in range(shp[0]):
  for j in range(shp[1]):
    do_something(myarray[i][j])

【问题讨论】:

    标签: python arrays numpy


    【解决方案1】:

    您应该查看ravelnditerndindex

    # For the simple case
    for value in np.nditer(a):
        do_something_with(value)
    
    # This is similar to above
    for value in a.ravel():
        do_something_with(value)
    
    # Or if you need the index
    for idx in np.ndindex(a.shape):
        a[idx] = do_something_with(a[idx])
    

    另外,numpy 数组的索引是 a[i, j] 而不是 a[i][j]。在python中a[i, j]相当于用一个元组索引,即a[(i, j)]

    【讨论】:

    • 谢谢,你让我走上了正轨。我最终将使用 ndenumerate。
    【解决方案2】:

    您可以使用 numpy 数组的 flat 属性,它返回所有值的生成器(无论形状如何)。

    例如:

    >>> A = np.array([[1,2,3],[4,5,6]])
    >>> for x in A.flat:
    ...     print x
    1
    2
    3
    4
    5
    6
    

    您还可以按照返回的顺序设置值,例如像这样:

    >>> A.flat[:] = [x / 2 if x % 2 == 0 else x for x in A.flat]
    >>> A
    array([[1,  1,  3],
           [2,  5,  3]])
    

    我不确定flat 返回元素的顺序是否有任何保证(因为它会在内存中迭代元素,因此根据您的数组约定,您可能可能 让它始终保持不变,除非你真的是故意这样做的,但要小心......)

    这适用于任何维度。

    ** -- 编辑 -- **

    为了澄清我所说的“无法保证顺序”的意思,flat 返回的元素顺序没有改变,但我认为指望row1 = A.flat[:N] 这样的东西是不明智的,尽管它会起作用大多数时候。

    【讨论】:

      【解决方案3】:

      这可能是最简单的递归:

      a = numpy.array(range(30)).reshape(5, 3, 2)
      
      def recursive_do_something(array):
          if len(array.shape) == 1:
              for obj in array:
                  do_something(obj)
          else:
              for subarray in array:
                  recursive_do_something(subarray)
      
      recursive_do_something(a)
      

      如果你想要索引:

      a = numpy.array(range(30)).reshape(5, 3, 2)
      
      def do_something(x, indices):
          print(indices, x)
      
      def recursive_do_something(array, indices=None):
          indices = indices or []
          if len(array.shape) == 1:
              for obj in array:
                  do_something(obj, indices)
          else:
              for i, subarray in enumerate(array):
                  recursive_do_something(subarray, indices + [i])
      
      recursive_do_something(a)
      

      【讨论】:

      • 如果你想要索引和值,你可以简单地使用ndenumerate
      • 感谢您的建议,我不知道 numpy 有一个特定的 ndarray 枚举器。
      • 不错的方法!起初我确信递归是适用的,但我没有深入研究。
      【解决方案4】:

      查看 Python 的 itertools 模块。

      这将允许您按照以下方式做一些事情

      for lengths in product(shp[0], shp[1], ...):
          do_something(myarray[lengths[0]][lengths[1]]
      

      【讨论】:

        猜你喜欢
        • 2014-09-19
        • 1970-01-01
        • 1970-01-01
        • 2018-07-28
        • 2016-09-05
        • 2018-06-28
        • 2021-12-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多