คุณใช้ไวยากรณ์การแบ่งจุดไข่ปลาใน Python อย่างไร


คำตอบ:


102

Ellipsisหรือ...ไม่ใช่คุณสมบัติที่ซ่อนอยู่มันเป็นค่าคงที่ มันค่อนข้างแตกต่างกับพูด javascript ES6 ซึ่งเป็นส่วนหนึ่งของไวยากรณ์ภาษา ไม่มีคลาสบิวอินหรือภาษางูหลามใช้ประโยชน์จากมัน

ดังนั้นไวยากรณ์ของมันจึงขึ้นอยู่กับคุณทั้งหมดหรือคนอื่นโดยการเขียนโค้ดเพื่อทำความเข้าใจ

Numpy ใช้มันตามที่ระบุไว้ในเอกสาร ตัวอย่างบางส่วนที่นี่

ในชั้นเรียนของคุณคุณจะใช้มันในลักษณะนี้:

>>> class TestEllipsis(object):
...     def __getitem__(self, item):
...         if item is Ellipsis:
...             return "Returning all items"
...         else:
...             return "return %r items" % item
... 
>>> x = TestEllipsis()
>>> print x[2]
return 2 items
>>> print x[...]
Returning all items

แน่นอนว่ายังมีเป็นเอกสารหลามและอ้างอิงภาษา แต่สิ่งเหล่านั้นไม่ค่อยเป็นประโยชน์


6
ดูค่อนข้างเสียตั้งแต่วิธี "propper" ที่จะพูดรายการทั้งหมดคือ >>> x [:] >>> x [:, 1: 2]
Ronny

30
@ Ronny: ประเด็นคือเพื่อแสดงให้เห็นถึงการใช้งานที่กำหนดเองของ Ellipsis
nosklo

7
ดูเหมือนว่าลิงก์จะใช้งานไม่ได้
SwiftsNamesake

231

จุดไข่ปลาจะใช้ในการ numpy เพื่อแบ่งโครงสร้างข้อมูลมิติที่สูงขึ้น

มันออกแบบมาเพื่อหมายถึงณ จุดนี้ใส่เป็นชิ้นเต็มรูปแบบจำนวนมาก ( :) เพื่อขยายชิ้นหลายมิติไปยังทุกมิติ

ตัวอย่าง :

>>> from numpy import arange
>>> a = arange(16).reshape(2,2,2,2)

ตอนนี้คุณมีเมทริกซ์ 4 มิติเรียง 2x2x2x2 ในการเลือกองค์ประกอบแรกทั้งหมดในมิติที่ 4 คุณสามารถใช้เครื่องหมายจุดไข่ปลา

>>> a[..., 0].flatten()
array([ 0,  2,  4,  6,  8, 10, 12, 14])

ซึ่งเทียบเท่ากับ

>>> a[:,:,:,0].flatten()
array([ 0,  2,  4,  6,  8, 10, 12, 14])

ในการติดตั้งใช้งานของคุณเองคุณมีอิสระที่จะเพิกเฉยต่อสัญญาที่กล่าวถึงข้างต้นและใช้สำหรับสิ่งที่คุณเห็นว่าเหมาะสม


บางทีฉันผิด แต่ไม่ใช่ว่าa[:,:,:,0]จะส่งคืนสำเนาและa[...,0]จะส่งคืน "มุมมอง" และไม่ใช่สำเนาหรือ ฉันพยายามวิ่งid()กับทั้งสองเวอร์ชันและสำหรับอาเรย์ 3 มิติ: a[:,:,:, 0], a[:,:,:, 1], a[:,:,:, 2] ทั้งหมดมีรหัสที่แตกต่างกันในขณะที่: a[..., 0], a[..., 1], a[..., 2] ทั้งหมดมีรหัสเดียวกัน
mohitsharma44

@ mohitsharma44 ไม่ได้อยู่ในเครื่องของฉัน;) id()ส่งคืนค่าเดียวกันสำหรับทั้งคู่ ตรวจสอบด้วย__array_interface__['data']แสดงที่อยู่หน่วยความจำเดียวกัน
BoltzmannBrain

ฉันพบว่าเราสามารถใช้งานa[indexes, ...]ในขณะที่ a เป็นอาร์เรย์ 1 มิติได้!
acgtyrant

1
จุดไข่ปลายังมีประโยชน์สำหรับโครงสร้างข้อมูลศูนย์ นี่เป็นวิธีเดียวที่ฉันรู้ว่าจะเขียนลงใน scalar numpy.ndarrays เช่น: my_scalar = np.asarray (3); my_scalar [... ] = 5. ถ้าคุณทำ my_scalar [:] = 5 คุณจะได้รับข้อผิดพลาดอย่างถูกต้องเนื่องจากไม่มีมิติ 0 สำหรับ: เพื่อวนซ้ำ
SuperElectric

1
@SuperElectric คุณยังสามารถใช้ my_scalar.itemset (scalarvalue) แน่นอน my_scalar [... ] = scalar_value นั้นสั้นกว่า แต่คุณพูดในความคิดเห็นด้านบนว่าเป็นวิธีเดียวที่คุณรู้ เพียงแค่ให้ทางเลือก
kamathln

70

นี่คือการใช้งานอื่นสำหรับ Ellipsis ซึ่งไม่มีส่วนเกี่ยวข้องกับชิ้น: ฉันมักจะใช้มันในการสื่อสารภายในเธรดกับคิวเป็นเครื่องหมายที่ส่งสัญญาณว่า "เสร็จสิ้น"; มันคือวัตถุมันเป็นซิงเกิลตันและชื่อของมันหมายถึง "ขาด" และไม่ใช่ None ที่มากเกินไป (ซึ่งสามารถใส่ในคิวเป็นส่วนหนึ่งของการไหลของข้อมูลปกติ) YMMV


14
มันอาจจะไม่ชัดเจนกว่าที่จะพูดว่า: "Done = object ()" ที่ไหนสักแห่งแล้วใช้มันเหรอ?
แบรนดอนโรดส์

12
ไม่จำเป็น - คุณต้องพูดเสร็จแล้ว = วัตถุ () ที่ไหนสักแห่ง ค่าของ Sentinel ไม่จำเป็นต้องเป็นเรื่องเลวร้าย - และการใช้งาน Python singletons ที่แทบจะไร้ประโยชน์เพราะ Sentinel นั้นไม่ใช่ IMO ที่น่ากลัว (Ellipsis และ () เป็นสิ่งที่ฉันใช้ซึ่งไม่มีใครจะสับสน)
Rick Copeland

6
เกี่ยวกับ Done = object () ฉันคิดว่าการใช้ Ellipsis ดีกว่าโดยเฉพาะถ้าคุณใช้เพื่อการสื่อสารกับคิว หากคุณเปลี่ยนจากการสื่อสารภายในไปเป็นการสื่อสารระหว่างกระบวนการ id (เสร็จสิ้น) จะไม่เหมือนกันในกระบวนการอื่นและไม่มีอะไรแยกแยะวัตถุหนึ่งจากอีกวัตถุหนึ่ง รหัสของ Ellipsis จะไม่เหมือนกัน แต่อย่างน้อยชนิดจะเหมือนกัน - นี่คือจุดของซิงเกิล
อุโมงค์ Reid

คำถามบอกว่า "คุณใช้จุดไข่ปลา" ได้อย่างไร แต่ฉันเชื่อว่าคุณใช้วิธีนี้ผิด มันมีการตีความมากมาย แต่ฉันคิดว่าสิ่งที่ถูกต้องคือ: "Ellipsis ใช้อย่างไร" คือ "ฉันควรทำอย่างไรเพื่อใช้ประโยชน์จาก Ellipsis ในรหัสของฉัน"
Lyndon White

6

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

สิ่งที่ฉันคิดว่าสำคัญที่จะเน้นและที่ขาดหายไปกับคำตอบอื่น ๆ ก็คือมันสามารถใช้งานได้แม้ว่าจะไม่มีมิติที่จะเติมอีก

ตัวอย่าง:

>>> from numpy import arange
>>> a = arange(4).reshape(2,2)

สิ่งนี้จะทำให้เกิดข้อผิดพลาด:

>>> a[:,0,:]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: too many indices for array

สิ่งนี้จะได้ผล:

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