[英]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
函数在t
和s
获取连续的条目对(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.