ทำซ้ำบนอาร์เรย์ numpy


136

มีทางเลือกอื่นที่ละเอียดน้อยกว่านี้หรือไม่:

for x in xrange(array.shape[0]):
    for y in xrange(array.shape[1]):
        do_stuff(x, y)

ฉันคิดสิ่งนี้:

for x, y in itertools.product(map(xrange, array.shape)):
    do_stuff(x, y)

ซึ่งบันทึกการเยื้องหนึ่งครั้ง แต่ก็ยังค่อนข้างน่าเกลียด

ฉันหวังว่าจะมีบางอย่างที่ดูเหมือนรหัสเทียมนี้:

for x, y in array.indices:
    do_stuff(x, y)

มีอะไรแบบนั้นหรือไม่?


ฉันอยู่ใน python 2.7 และกำลังใช้โซลูชันของคุณกับ itertools ฉันอ่านในความคิดเห็นว่าการใช้ itertools จะเร็วกว่า อย่างไรก็ตาม (อาจเป็นเพราะฉันอยู่ใน 2.7) ฉันต้องแกะแผนที่ในลูปสำหรับ for x, y in itertools.product(*map(xrange, array.shape)):
ALM

มีหน้าหนึ่งในการอ้างอิง NumPy ชื่อ "Iterating Over Arrays": docs.scipy.org/doc/numpy/reference/arrays.nditer.html
Casey

คำตอบ:


188

ฉันคิดว่าคุณกำลังมองหาndenumerate

>>> a =numpy.array([[1,2],[3,4],[5,6]])
>>> for (x,y), value in numpy.ndenumerate(a):
...  print x,y
... 
0 0
0 1
1 0
1 1
2 0
2 1

เกี่ยวกับประสิทธิภาพ ช้ากว่าความเข้าใจในรายการเล็กน้อย

X = np.zeros((100, 100, 100))

%timeit list([((i,j,k), X[i,j,k]) for i in range(X.shape[0]) for j in range(X.shape[1]) for k in range(X.shape[2])])
1 loop, best of 3: 376 ms per loop

%timeit list(np.ndenumerate(X))
1 loop, best of 3: 570 ms per loop

หากคุณกังวลเกี่ยวกับประสิทธิภาพคุณสามารถเพิ่มประสิทธิภาพได้อีกเล็กน้อยโดยดูที่การใช้งานndenumerateซึ่งทำ 2 อย่างคือการแปลงเป็นอาร์เรย์และการวนซ้ำ ถ้าคุณรู้ว่าคุณมีอาร์เรย์คุณสามารถเรียกใช้.coordsแอตทริบิวต์ของ flat iterator

a = X.flat
%timeit list([(a.coords, x) for x in a.flat])
1 loop, best of 3: 305 ms per loop

1
สังเกตว่าสิ่งนี้ใช้งานได้ แต่ช้าอย่างไม่น่าเชื่อ คุณควรทำซ้ำด้วยตนเองดีกว่า
Marty

45

หากคุณต้องการเพียงดัชนีคุณสามารถลองnumpy.ndindex:

>>> a = numpy.arange(9).reshape(3, 3)
>>> [(x, y) for x, y in numpy.ndindex(a.shape)]
[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]

15

ดูnditer

import numpy as np
Y = np.array([3,4,5,6])
for y in np.nditer(Y, op_flags=['readwrite']):
    y += 3

Y == np.array([6, 7, 8, 9])

y = 3จะไม่ทำงาน, การใช้งานy *= 0และการy += 3แทน


2
หรือใช้ y [... ] = 3
Donald Hobson
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.