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
; and the resulting y
coordinates (result of y=f(x), in this case sin(x)
) in the array s
. 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:
基本上,这将我们的(x,y)数据点的x坐标存储在数组t中;以及在数组s中得到的y坐标(y = f(x)的结果,在这种情况下为sin(x))。然后,使用numpy.nditer函数获取t和s中的连续条目对非常方便,表示数据点的(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的方法 - 但我仍然喜欢在somearray中指定x,y的便利,并直接获取坐标在循环。
After some messing about with numpy
documentation, I came up with this getXyIter
function:
在讨论了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))
... 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的版本中完成吗?
2 个解决方案
#1
3
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))
#2
1
for x, y in zip(t,s):
. For 1d arrays, it's really that simple.
for x,y in zip(t,s):.对于1d阵列,它真的很简单。
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. If you have to deal with N-d arrays, this may or may not be what you want.
对于> 1D阵列,迭代移动通过返回(N-1)D阵列的最后一维。如果你必须处理N-d阵列,这可能是也可能不是你想要的。
Regardless, it's unquestionably portable, and iterating on array objects is intended to support this kind of usecase :)
无论如何,它毫无疑问是可移植的,并且迭代数组对象旨在支持这种用例:)
#1
3
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))
#2
1
for x, y in zip(t,s):
. For 1d arrays, it's really that simple.
for x,y in zip(t,s):.对于1d阵列,它真的很简单。
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. If you have to deal with N-d arrays, this may or may not be what you want.
对于> 1D阵列,迭代移动通过返回(N-1)D阵列的最后一维。如果你必须处理N-d阵列,这可能是也可能不是你想要的。
Regardless, it's unquestionably portable, and iterating on array objects is intended to support this kind of usecase :)
无论如何,它毫无疑问是可移植的,并且迭代数组对象旨在支持这种用例:)