Rozważmy specyfikację numpy
tablic, typowe dla określenia matplotlib
wykreślania danych:Iterowanie dwóch tablic, bez nditera, w numpy?
t = np.arange(0.0,1.5,0.25)
s = np.sin(2*np.pi*t)
Zasadniczo, przechowuje współrzędne x
naszych (x,y)
punktów danych w tablicy t
; i uzyskane współrzędne y
(wynik y = f (x), w tym przypadku sin(x)
) w macierzy s
. Następnie, to jest bardzo wygodny w użyciu funkcji numpy.nditer
celu uzyskania kolejnych par wpisów w t
i s
, reprezentujący (x,y)
współrzędna punktu danych, na przykład:
for x, y in np.nditer([t,s]):
print("xy: %f:%f" % (x,y))
So, próbuję następujący fragment jak 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))
... a wyniki są następujące:
$ 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 - okazuje się, że the iterator object nditer, introduced in NumPy 1.6, nie jest dostępny w wersji numpy
mojej instalacji Pythona 2.7.
Tak, jak chciałbym wesprzeć tę konkretną wersję też, że muszę znaleźć sposób pracy dla starszych numpy
- ale ja nadal jak wygody po prostu określając for x,y in somearray
, a uzyskanie współrzędnych bezpośrednio w pętla.
Po pewnym ingerować numpy
dokumentacji, wymyśliłem tego getXyIter
funkcję:
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))
... co wydaje się działać prawidłowo
$ 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
Moje pytanie brzmi - czy to jest droga , ten rodzaj iteracji powinien zostać wykonany w wersjach numpy < 1.6.0?