简体   繁体   English

在numpy中迭代两个没有nditer的数组?

[英]Iterating two arrays, without nditer, in numpy?

Consider a specification of numpy arrays, typical for specifying matplotlib plotting data: 考虑numpy数组的规范,通常用于指定matplotlib绘图数据:

t = np.arange(0.0,1.5,0.25)
s = np.sin(2*np.pi*t) 

Basically, this stores the x coordinates of our (x,y) data points in the array t ; 基本上,这将我们(x,y)数据点的x坐标存储在数组t and the resulting y coordinates (result of y=f(x), in this case sin(x) ) in the array s . 以及数组s中的y坐标(y = f(x)的结果,在这种情况下为sin(x) )。 Then, it is very convenient to use the numpy.nditer function to obtain consecutive pairs of entries in t and s , representing the (x,y) coordinate of a data point, as in: 然后,使用numpy.nditer函数在ts获取连续的条目对(x,y)表示数据点的(x,y)坐标(x,y)非常方便,如下所示:

for x, y in np.nditer([t,s]):
  print("xy: %f:%f" % (x,y))

So, I'm trying the following snippet as test.py : 因此,我正在尝试将以下代码段作为test.py

import numpy as np
print("numpy version {0}".format(np.__version__))
t = np.arange(0.0,1.5,0.25)   ; print("t", ["%+.2e"%i for i in t])
s = np.sin(2*np.pi*t)         ; print("s", ["%+.2e"%i for i in s])
print("i", ["% 9d"%i for i in range(0, len(t))])
for x, y in np.nditer([t,s]):
  print("xy: %f:%f" % (x,y))

... and the results are: ...的结果是:

$ python3.2 test.py 
numpy version 1.7.0
t ['+0.00e+00', '+2.50e-01', '+5.00e-01', '+7.50e-01', '+1.00e+00', '+1.25e+00']
s ['+0.00e+00', '+1.00e+00', '+1.22e-16', '-1.00e+00', '-2.45e-16', '+1.00e+00']
i ['        0', '        1', '        2', '        3', '        4', '        5']
xy: 0.000000:0.000000
xy: 0.250000:1.000000
xy: 0.500000:0.000000
xy: 0.750000:-1.000000
xy: 1.000000:-0.000000
xy: 1.250000:1.000000

$ python2.7 test.py 
numpy version 1.5.1
('t', ['+0.00e+00', '+2.50e-01', '+5.00e-01', '+7.50e-01', '+1.00e+00', '+1.25e+00'])
('s', ['+0.00e+00', '+1.00e+00', '+1.22e-16', '-1.00e+00', '-2.45e-16', '+1.00e+00'])
('i', ['        0', '        1', '        2', '        3', '        4', '        5'])
Traceback (most recent call last):
  File "test.py", line 10, in <module>
    for x, y in np.nditer([t,s]):
AttributeError: 'module' object has no attribute 'nditer'

Ah - it turns out, that the iterator object nditer, introduced in NumPy 1.6 , is not available in the numpy version of my Python 2.7 installation. 嗯-事实证明, 在NumPy 1.6中引入的迭代器对象nditer在我的Python 2.7安装的numpy版本中不可用。

So, as I'd like to support that particular version too, I'd need to find a way working for older numpy - but I'd still like the convenience of just specifying for x,y in somearray , and getting the coordinates directly in the loop. 因此,由于我也想支持该特定版本,因此我需要找到一种用于较早的numpy -但我仍希望仅for x,y in somearray指定for x,y in somearray并直接获取坐标的便利性在循环。

After some messing about with numpy documentation, I came up with this getXyIter function: 在对numpy文档进行了一些弄乱之后,我getXyIter了这个getXyIter函数:

import numpy as np
print("numpy version {0}".format(np.__version__))
t = np.arange(0.0,1.5,0.25)   ; print("t", ["%+.2e"%i for i in t])
s = np.sin(2*np.pi*t)         ; print("s", ["%+.2e"%i for i in s])
print("i", ["% 9d"%i for i in range(0, len(t))])

def getXyIter(inarr):
  if np.__version__ >= "1.6.0":
    return np.nditer(inarr.tolist())
  else:
    dimensions = inarr.shape
    xlen = dimensions[1]
    xinds = np.arange(0, xlen, 1)
    return np.transpose(np.take(inarr, xinds, axis=1))

for x, y in getXyIter(np.array([t,s])):
  print("xyIt: %f:%f" % (x,y))

for x, y in np.nditer([t,s]):
  print("xynd: %f:%f" % (x,y))

... which seems to work fine ...这似乎很好

$ python2.7 test.py 
numpy version 1.5.1
('t', ['+0.00e+00', '+2.50e-01', '+5.00e-01', '+7.50e-01', '+1.00e+00', '+1.25e+00'])
('s', ['+0.00e+00', '+1.00e+00', '+1.22e-16', '-1.00e+00', '-2.45e-16', '+1.00e+00'])
('i', ['        0', '        1', '        2', '        3', '        4', '        5'])
xyIt: 0.000000:0.000000
xyIt: 0.250000:1.000000
xyIt: 0.500000:0.000000
xyIt: 0.750000:-1.000000
xyIt: 1.000000:-0.000000
xyIt: 1.250000:1.000000
Traceback (most recent call last):
  File "test.py", line 23, in <module>
    for x, y in np.nditer([t,s]):
AttributeError: 'module' object has no attribute 'nditer'
$ python3.2 test.py 
numpy version 1.7.0
t ['+0.00e+00', '+2.50e-01', '+5.00e-01', '+7.50e-01', '+1.00e+00', '+1.25e+00']
s ['+0.00e+00', '+1.00e+00', '+1.22e-16', '-1.00e+00', '-2.45e-16', '+1.00e+00']
i ['        0', '        1', '        2', '        3', '        4', '        5']
xyIt: 0.000000:0.000000
xyIt: 0.250000:1.000000
xyIt: 0.500000:0.000000
xyIt: 0.750000:-1.000000
xyIt: 1.000000:-0.000000
xyIt: 1.250000:1.000000
xynd: 0.000000:0.000000
xynd: 0.250000:1.000000
xynd: 0.500000:0.000000
xynd: 0.750000:-1.000000
xynd: 1.000000:-0.000000
xynd: 1.250000:1.000000

My question is - is this the way, this kind of iteration is supposed to be done, in versions of numpy < 1.6.0? 我的问题是-以这种方式,应该在numpy <1.6.0版本中进行这种迭代吗?

How about concatenating the two vectors into an array: 如何将两个向量串联成一个数组:

for x,y in np.c_[t,s]:
    print("xy: %f:%f" % (x,y))

This gives 这给

xy: 0.000000:0.000000
xy: 0.250000:1.000000
xy: 0.500000:0.000000
xy: 0.750000:-1.000000
xy: 1.000000:-0.000000
xy: 1.250000:1.000000

If you want to iterate so you can save memory, you can use the itertools.izip function: 如果要进行迭代以节省内存,则可以使用itertools.izip函数:

for x,y in itertools.izip(t,s):
    print("xy: %f:%f" % (x,y))

for x, y in zip(t,s): . for x, y in zip(t,s): For 1d arrays, it's really that simple. 对于一维数组,实际上就是这么简单。

Verified to work in both Python 2 and Python 3. zip() returns a list on Python2 though, so as DiggyF suggests, itertools.izip() may be more appropriate for large arrays. 经过验证可同时在Python 2和Python 3中使用。zip()返回Python2上的列表,因此正如DiggyF所建议的那样, itertools.izip()可能更适合于大型数组。

For >1D arrays, iteration moves through the last dimension returning (N-1)D arrays. 对于> 1D数组,迭代遍历最后一个返回(N-1)D数组的维。 If you have to deal with Nd arrays, this may or may not be what you want. 如果您必须处理Nd阵列,则可能是您想要的,也可能不是。

Regardless, it's unquestionably portable, and iterating on array objects is intended to support this kind of usecase :) 无论如何,它无疑是可移植的,并且在数组对象上进行迭代旨在支持这种用例:)

This worked for me 这对我有用

x = x.flatten()
y = y.flatten()
for i,j in zip(x,y):
     #do something

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

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