【问题标题】:Is there a way to convert a multi_index into a int string / list / array?有没有办法将 multi_index 转换为 int 字符串/列表/数组?
【发布时间】:2019-05-23 21:08:04
【问题描述】:

我想将 numpy 中给定数组的值更改为数组其他元素的乘积。因此,我想提取 multi_index 并对其进行操作,以便我可以识别位置并使用它。 (例如,遍历所有元素并始终执行“数组中的当前位置=数组中的下一个位置+位置上方”

我试图用当前位置的 multi_index 调用一个函数,并希望该函数接受它,例如增加一位。 ( ---> while n>=length 否则 ---> )

import numpy as np;

def fill(multi_index):
    "This will get the new value of the current iteration value judgeing from its index"
    return a[(multi_index + <0,1>) + (multi_index + <0,-1>) + (multi_index + <1,0>) + (multi_index + <-1,0>)]

#a = np.random.uniform(0, 100, size=(100, 100))
a = np.arange(6).reshape(2,3)

it = np.nditer(a, flags=['multi_index'], op_flags=['readwrite'])
while not it.finished:
    it[0] = fill(it.multi_index)
    print(it[0])
    it.iternext()

"""for x in np.nditer(a, flags=['multi_index'], op_flags=['readwrite']):

    print(x)"""

我不明白如何从 multi_index 中提取实际的“坐标”。我对python有点陌生,所以如果可能的话,请尝试彻底解释它。谢谢。

编辑:在我只使用 C++ 和一点 Java 编写代码之前,我以前主要使用数组(在 c++ 中会是这样的:

int main() { 
  int a[100][100];
  for (int i=1, i<=a.length-1, i++) { 
    for (int j=1, i<=a.width-1, j++) { 
      a[i][j] = 1/4 (a[i][j+1]+a[i][j-1]+a[i+1][j]+a[i-1][j]);
    } 
  } 
return 0;
}

【问题讨论】:

  • 远离nditer,尤其是初学者。它不会提高迭代速度。用普通的索引 for 循环显示你正在尝试做的事情。
  • 提供示例输入和首选输出也会有所帮助
  • 通常输入是一个 100x100 的随机值数组,并且在迭代的各个步骤中,数组中的每个元素将被设置为相邻元素的 1/4。经过 1000 次左右的迭代,完成的数组将被打印出来。为了将元素的值更改为其相邻元素的乘积,我需要提取其“坐标”并(在单独的函数填充中)通过简单的乘法获得新值。目前填充功能中还没有任何内容。
  • 在 for 循环中:python for x in for x in np.nditer(a, flags=['multi_index'], op_flags=['readwrite']: a[x] = 1/4 ( a[mutil_index + &lt;0,1&gt;] + a[mutil_index + &lt;0, -1&gt;] + a[mutil_index + &lt;1,1&gt;] + a[mutil_index + &lt;-1,-1&gt;] )

标签: python numpy multidimensional-array array-indexing


【解决方案1】:
In [152]: a = np.arange(6).reshape(2,3)                                                                  
In [153]: a                                                                                              
Out[153]: 
array([[0, 1, 2],
       [3, 4, 5]])

让我们运行您的nditer 并查看它的值:

In [157]: it = np.nditer(a, flags=['multi_index'], op_flags=['readwrite'])                               
In [158]: while not it.finished: 
     ...:     print(it.multi_index, a[it.multi_index], it[0], type(it[0])) 
     ...:     it.iternext() 
     ...:                                                                                                
(0, 0) 0 0 <class 'numpy.ndarray'>
(0, 1) 1 1 <class 'numpy.ndarray'>
(0, 2) 2 2 <class 'numpy.ndarray'>
(1, 0) 3 3 <class 'numpy.ndarray'>
(1, 1) 4 4 <class 'numpy.ndarray'>
(1, 2) 5 5 <class 'numpy.ndarray'>

在每次迭代中,multiindexi,j 索引的元组。 a[it.multiindex] 然后从数组中选择该项目。但it[0] 也是该项目,但包装为 0d 数组。如果您对 0d 数组(形状 ())的想法不满意,那么 nditer 不适合您(目前)。

如果您只想要顺序索引元组,ndindex 也可以:

In [162]: list(np.ndindex(a.shape))                                                                      
Out[162]: [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2)]

(实际上,np.lib.index_tricks.py 表明ndindex 使用了nditer 多索引。nditernumpy Python 级代码中并不常用。)

或者获取索引加值:

In [177]: list(np.ndenumerate(a))                                                                        
Out[177]: [((0, 0), 0), ((0, 1), 1), ((0, 2), 2), ((1, 0), 3), ((1, 1), 4), ((1, 2), 5)]

只是按顺序排列的值:

In [178]: a.ravel()                                                                                      
Out[178]: array([0, 1, 2, 3, 4, 5])

但是,在numpy 中,我们根本不喜欢迭代。相反,我们尝试使用快速编译的numpy 方法编写适用于整个数组的代码。数组迭代很慢,比列表迭代慢。

===

看起来你的迭代,在某种风格化的意义上,是:

for i in range(n):
    for j in range(m):
         a[i,j] = ( a[i,j+1] + a[i,j-1] + a[i+1,j] + a[i-1,j] )/4 

有些细节需要担心。那么边缘呢,j+/-1 越界了?并且这个计算是连续的,所以a[i,j] 取决于刚刚对a[i,j-1] 所做的更改;还是被缓冲了?

一般来说,像这样的数组上的顺序迭代计算不适合numpy

另一方面,缓冲计算可以用整个数组切片很好地完成

x[1:-1, 1:-1] = (x[:,:-1]+x[:,1:]+x[:-1,:]+x[1:,:])/4

scipy 中还有一些卷积函数可以在移动窗口上执行计算。

【讨论】:

  • 通常输入是一个 100x100 的随机值数组,并且在迭代的各个步骤中,数组中的每个元素将被设置为相邻元素的 1/4。经过 1000 次左右的迭代,完成的数组将被打印出来。为了将元素的值更改为其相邻元素的乘积,我需要提取其“坐标”并(在单独的函数填充中)通过简单的乘法获得新值。目前,填充功能中还没有任何内容。我并不特别关心它们是 0d 数组(我想是简单的标量?)
  • 也许有一种快速编译的 numpy 方法可用于此类迭代,但这是我目前能找到的最佳方法。在我只使用 C++ 和一点 Java 编写代码之前,我以前主要使用数组(在 C++ 中它会是这样的: int main() { for (int i=1, i
  • 我想你会对numpy中这种迭代的速度感到非常失望。
  • 这看起来真的很好,你能解释一下最后一个代码位是如何工作的吗?我还决定我可能在 C++ 中有更好的计算时间,并且有一个关于这个主题的新问题。
  • 制作一个简单的一维数组(例如np.arange(12))并尝试这种成对的差异计算,arr[1:]-arr[:-1]。这应该让您对正在发生的事情有所了解。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-04-04
  • 1970-01-01
  • 2022-01-21
  • 2023-01-30
  • 2020-09-17
  • 2021-05-17
  • 1970-01-01
相关资源
最近更新 更多