9

考虑一个numpy数组规范,通常用于指定matplotlib绘图数据:

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

基本上,这将x我们数据点的坐标存储(x,y)在数组中t;以及数组中的结果y坐标(在本例中为 y=f(x) 的结果) 。然后,使用该函数可以很方便地获取 和 中的连续条目对,表示一个数据点的坐标,如下所示:sin(x)snumpy.nditerts(x,y)

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

所以,我正在尝试以下代码段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))

...结果是:

$ 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'

啊 - 事实证明,在 NumPy 1.6 中引入的迭代器对象 nditer 在numpy我的 Python 2.7 安装版本中不可用。

因此,由于我也想支持该特定版本,我需要找到一种适用于旧版本的方法numpy- 但我仍然希望仅指定for x,y in somearray,并直接在循环中获取坐标的便利。

在弄乱了numpy文档之后,我想出了这个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))

...这似乎工作正常

$ 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

我的问题是 - 在 numpy < 1.6.0 的版本中,这种迭代应该是这样吗?

4

3 回答 3

5

如何将两个向量连接成一个数组:

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

这给

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

如果要迭代以节省内存,可以使用以下itertools.izip功能:

for x,y in itertools.izip(t,s):
    print("xy: %f:%f" % (x,y))
于 2013-05-20T11:59:26.830 回答
2

for x, y in zip(t,s):. 对于一维数组,它真的就这么简单。

已验证可在 Python 2 和 Python 3 中工作。不过,zip() 在 Python2 上返回一个列表,正如 DiggyF 所建议的那样,itertools.izip()它可能更适合大型数组。

对于 >1D 数组,迭代移动通过返回 (N-1)D 数组的最后一维。如果您必须处理 Nd 阵列,这可能是也可能不是您想要的。

无论如何,它无疑是可移植的,并且迭代数组对象旨在支持这种用例:)

于 2013-05-20T12:17:33.780 回答
0

这对我有用

x = x.flatten()
y = y.flatten()
for i,j in zip(x,y):
     #do something
于 2019-09-12T16:54:41.813 回答