ใช้มุมมองและรับรันไทม์ฟรี! ขยายn-dim
อาร์เรย์ทั่วไปเป็นn+1-dim
แนะนำในNumPy1.10.0
เราสามารถใช้ประโยชน์จากnumpy.broadcast_to
การสร้าง3D
มุมมองใน2D
อาร์เรย์อินพุต ประโยชน์ที่ได้คือไม่มีค่าใช้จ่ายหน่วยความจำเพิ่มเติมและรันไทม์ฟรี สิ่งนี้จำเป็นอย่างยิ่งในกรณีที่อาร์เรย์มีขนาดใหญ่และเราสามารถทำงานกับมุมมองได้ นอกจากนี้ยังสามารถใช้ได้กับn-dim
กรณีทั่วไป
ฉันจะใช้คำนี้stack
แทนcopy
เนื่องจากผู้อ่านอาจสับสนกับการคัดลอกอาร์เรย์ที่สร้างสำเนาหน่วยความจำ
กองตามแกนแรก
หากเราต้องการซ้อนอินพุตarr
ตามแกนแรกวิธีแก้ปัญหาnp.broadcast_to
ในการสร้าง3D
มุมมองจะเป็น -
np.broadcast_to(arr,(3,)+arr.shape)
กองตามแกนที่สาม / แกนสุดท้าย
ในการจัดเรียงอินพุตarr
ตามแกนที่สามวิธีการสร้าง3D
มุมมองจะเป็น -
np.broadcast_to(arr[...,None],arr.shape+(3,))
ถ้าเราต้องการจริงสำเนาหน่วยความจำที่เราสามารถเสมอผนวก.copy()
มี ดังนั้นการแก้ปัญหาจะเป็น -
np.broadcast_to(arr,(3,)+arr.shape).copy()
np.broadcast_to(arr[...,None],arr.shape+(3,)).copy()
ต่อไปนี้เป็นวิธีการทำงานของการเรียงซ้อนสำหรับทั้งสองกรณีซึ่งแสดงพร้อมกับข้อมูลรูปร่างของเคสตัวอย่าง -
In [55]: arr = np.random.rand(4,5)
In [56]: np.broadcast_to(arr,(3,)+arr.shape).shape
Out[56]: (3, 4, 5)
In [57]: np.broadcast_to(arr[...,None],arr.shape+(3,)).shape
Out[57]: (4, 5, 3)
โซลูชันเดียวกันจะทำงานเพื่อขยายn-dim
อินพุตเพื่อn+1-dim
ดูเอาต์พุตตามแกนแรกและแกนสุดท้าย มาสำรวจกรณีสลัวที่สูงกว่ากัน -
กรณีอินพุต 3D:
In [58]: arr = np.random.rand(4,5,6)
In [59]: np.broadcast_to(arr,(3,)+arr.shape).shape
Out[59]: (3, 4, 5, 6)
In [60]: np.broadcast_to(arr[...,None],arr.shape+(3,)).shape
Out[60]: (4, 5, 6, 3)
กรณีอินพุต 4D:
In [61]: arr = np.random.rand(4,5,6,7)
In [62]: np.broadcast_to(arr,(3,)+arr.shape).shape
Out[62]: (3, 4, 5, 6, 7)
In [63]: np.broadcast_to(arr[...,None],arr.shape+(3,)).shape
Out[63]: (4, 5, 6, 7, 3)
และอื่น ๆ
การกำหนดเวลา
ลองใช้2D
กรณีตัวอย่างขนาดใหญ่และรับการกำหนดเวลาและตรวจสอบผลลัพธ์ว่าเป็นview
ไฟล์.
In [19]: arr = np.random.rand(1000,1000)
มาพิสูจน์กันว่าวิธีแก้ปัญหาที่เสนอนั้นเป็นมุมมองที่แท้จริง เราจะใช้การเรียงซ้อนตามแกนแรก (ผลลัพธ์จะคล้ายกันมากสำหรับการเรียงซ้อนตามแกนที่สาม) -
In [22]: np.shares_memory(arr, np.broadcast_to(arr,(3,)+arr.shape))
Out[22]: True
มาดูการกำหนดเวลาเพื่อแสดงว่ามันฟรี -
In [20]: %timeit np.broadcast_to(arr,(3,)+arr.shape)
100000 loops, best of 3: 3.56 µs per loop
In [21]: %timeit np.broadcast_to(arr,(3000,)+arr.shape)
100000 loops, best of 3: 3.51 µs per loop
เป็นมุมมองที่เพิ่มขึ้นN
จาก3
การ3000
เปลี่ยนแปลงอะไรในการกำหนดเวลาและทั้งสองมีเล็กน้อยต่อหน่วยระยะเวลา ดังนั้นจึงมีประสิทธิภาพทั้งในหน่วยความจำและประสิทธิภาพ!
b[:,:,0]
, และb[:,:,1]
b[:,:,2]
ชิ้นส่วนมิติที่สามแต่ละชิ้นเป็นสำเนาของอาร์เรย์ 2D ดั้งเดิมprint(b)
นี้ไม่เป็นที่เห็นได้ชัดเพียงแค่มองไปที่