“ จุดสามจุด” ใน Python หมายถึงอะไรเมื่อสร้างดัชนีสิ่งที่ดูเหมือนตัวเลข


90

ความหมายของx[...]ด้านล่างคืออะไร?

a = np.arange(6).reshape(2,3)
for x in np.nditer(a, op_flags=['readwrite']):
    x[...] = 2 * x

1
นั่นไม่ใช่รายการ
user2357112 รองรับ Monica


1
วิธีที่สนุกต้องเข้าใจนี่คือการพูดคุยของ James Powell youtube.com/watch?v=65_-6kEAq58
SARose

คำตอบ:


70

ในขณะที่เสนอซ้ำวัตถุ Python Ellipsis ทำอะไร? ตอบคำถามในpythonบริบททั่วไปnditerฉันคิดว่าการใช้ในลูปต้องเพิ่มข้อมูล

https://docs.scipy.org/doc/numpy/reference/arrays.nditer.html#modifying-array-values

การกำหนดปกติใน Python เพียงแค่เปลี่ยนการอ้างอิงในพจนานุกรมตัวแปรท้องถิ่นหรือทั่วโลกแทนที่จะแก้ไขตัวแปรที่มีอยู่ในตำแหน่ง ซึ่งหมายความว่าการกำหนดให้กับ x จะไม่ใส่ค่าลงในองค์ประกอบของอาร์เรย์ แต่เป็นการเปลี่ยน x จากการอ้างอิงองค์ประกอบอาร์เรย์เป็นการอ้างอิงถึงค่าที่คุณกำหนด ในการแก้ไของค์ประกอบของอาร์เรย์จริง ๆ ควรทำดัชนี x ด้วยจุดไข่ปลา

ส่วนนั้นประกอบด้วยตัวอย่างโค้ดของคุณ

ดังนั้นในคำพูดของฉันการx[...] = ...ปรับเปลี่ยนxในสถานที่ x = ...จะทำให้ลิงก์ไปยังnditerตัวแปรเสียหายและไม่เปลี่ยนแปลง มันเหมือนกับx[:] = ...แต่ใช้ได้กับอาร์เรย์ทุกมิติ (รวมถึง 0d) ในบริบทxนี้ไม่ใช่แค่ตัวเลข แต่เป็นอาร์เรย์

บางทีสิ่งที่ใกล้เคียงที่สุดสำหรับการnditerวนซ้ำนี้หากไม่มีnditerคือ:

In [667]: for i, x in np.ndenumerate(a):
     ...:     print(i, x)
     ...:     a[i] = 2 * x
     ...:     
(0, 0) 0
(0, 1) 1
...
(1, 2) 5
In [668]: a
Out[668]: 
array([[ 0,  2,  4],
       [ 6,  8, 10]])

สังเกตว่าฉันต้องจัดทำดัชนีและแก้ไขa[i]โดยตรง ฉันไม่สามารถใช้, x = 2*x. ในการวนซ้ำxนี้เป็นสเกลาร์จึงไม่เปลี่ยนแปลง

In [669]: for i,x in np.ndenumerate(a):
     ...:     x[...] = 2 * x
  ...
TypeError: 'numpy.int32' object does not support item assignment

แต่ในnditerกรณีนี้xคืออาร์เรย์ 0d และไม่แน่นอน

In [671]: for x in np.nditer(a, op_flags=['readwrite']):
     ...:     print(x, type(x), x.shape)
     ...:     x[...] = 2 * x
     ...:     
0 <class 'numpy.ndarray'> ()
4 <class 'numpy.ndarray'> ()
...

และเนื่องจากเป็น 0d x[:]จึงไม่สามารถใช้แทนx[...]

----> 3     x[:] = 2 * x
IndexError: too many indices for array

การทำซ้ำอาร์เรย์ที่ง่ายขึ้นอาจให้ข้อมูลเชิงลึก:

In [675]: for x in a:
     ...:     print(x, x.shape)
     ...:     x[:] = 2 * x
     ...:     
[ 0  8 16] (3,)
[24 32 40] (3,)

iterates นี้ในแถว (ที่ 1 มซำ) aของ xจากนั้นเป็นอาร์เรย์ 1d และสามารถแก้ไขได้ด้วยx[:]=...หรือx[...]=....

และถ้าผมเพิ่มexternal_loopธงจากการต่อไปส่วน , xตอนนี้เป็นอาร์เรย์ 1D และx[:] =จะทำงาน แต่x[...] =ยังคงใช้งานได้และเป็นเรื่องทั่วไป x[...]จะใช้nditerตัวอย่างอื่น ๆทั้งหมด

In [677]: for x in np.nditer(a, op_flags=['readwrite'], flags=['external_loop']):
     ...:     print(x, type(x), x.shape)
     ...:     x[...] = 2 * x
[ 0 16 32 48 64 80] <class 'numpy.ndarray'> (6,)

เปรียบเทียบการทำซ้ำแถวอย่างง่ายนี้ (บนอาร์เรย์ 2d):

In [675]: for x in a:
     ...:     print(x, x.shape)
     ...:     x[:] = 2 * x
     ...:     
[ 0  8 16] (3,)
[24 32 40] (3,)

iterates นี้ในแถว (ที่ 1 มซำ) aของ xจากนั้นเป็นอาร์เรย์ 1d และสามารถแก้ไขได้ด้วยx[:] = ...หรือx[...] = ....

อ่านและทดลองกับnditerหน้านี้จนจบ ด้วยตัวมันเองnditerไม่ได้มีประโยชน์ในpython. มันไม่ได้เพิ่มความเร็วในการย้ำ - cythonไม่ได้จนกว่าคุณพอร์ตรหัสของคุณ np.ndindexเป็นหนึ่งในไม่กี่รวบรวมฟังก์ชั่นที่ใช้numpynditer


โปรดทราบว่าสิ่งต่างๆเช่น x [1,:, ... ] ก็เป็นไวยากรณ์ที่อนุญาตเช่นกัน เหลือไว้อ้างอิงในอนาคต
borgr
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.