นี่คือวิธีที่ numpy ใช้การจัดทำดัชนีขั้นสูงเพื่อกระจายรูปร่างของอาร์เรย์ เมื่อคุณผ่าน0
สำหรับดัชนีแรกและy
สำหรับดัชนีที่ผ่านมา numpy จะออกอากาศจะเป็นรูปร่างเช่นเดียวกับ0
y
ความเท่าเทียมกันดังต่อไปนี้ถือ: x[0,:,:,y] == x[(0, 0, 0),:,:,y]
. นี่คือตัวอย่าง
import numpy as np
x = np.arange(120).reshape(2,3,4,5)
y = np.array([0,2,4])
np.equal(x[0,:,:,y], x[(0, 0, 0),:,:,y]).all()
# returns:
True
ตอนนี้เนื่องจากคุณกำลังผ่านดัชนีสองชุดอย่างมีประสิทธิภาพคุณกำลังใช้ API การจัดทำดัชนีขั้นสูงเพื่อจัดทำดัชนี (ในกรณีนี้) คู่ของดัชนี
x[(0, 0, 0),:,:,y])
# equivalent to
[
x[0,:,:,y[0]],
x[0,:,:,y[1]],
x[0,:,:,y[2]]
]
# equivalent to
rows = np.array([0, 0, 0])
cols = y
x[rows,:,:,cols]
# equivalent to
[
x[r,:,:,c] for r, c in zip(rows, columns)
]
y
ซึ่งมีมิติที่แรกที่เดียวกับความยาวของ นี่คือสิ่งที่คุณเห็น
ตัวอย่างเช่นดูอาร์เรย์ที่มี 4 มิติซึ่งอธิบายไว้ในอันถัดไป:
x = np.arange(120).reshape(2,3,4,5)
y = np.array([0,2,4])
# x looks like:
array([[[[ 0, 1, 2, 3, 4], -+ =+
[ 5, 6, 7, 8, 9], Sheet1 |
[ 10, 11, 12, 13, 14], | |
[ 15, 16, 17, 18, 19]], -+ |
Workbook1
[[ 20, 21, 22, 23, 24], -+ |
[ 25, 26, 27, 28, 29], Sheet2 |
[ 30, 31, 32, 33, 34], | |
[ 35, 36, 37, 38, 39]], -+ |
|
[[ 40, 41, 42, 43, 44], -+ |
[ 45, 46, 47, 48, 49], Sheet3 |
[ 50, 51, 52, 53, 54], | |
[ 55, 56, 57, 58, 59]]], -+ =+
[[[ 60, 61, 62, 63, 64],
[ 65, 66, 67, 68, 69],
[ 70, 71, 72, 73, 74],
[ 75, 76, 77, 78, 79]],
[[ 80, 81, 82, 83, 84],
[ 85, 86, 87, 88, 89],
[ 90, 91, 92, 93, 94],
[ 95, 96, 97, 98, 99]],
[[100, 101, 102, 103, 104],
[105, 106, 107, 108, 109],
[110, 111, 112, 113, 114],
[115, 116, 117, 118, 119]]]])
x
มีรูปแบบต่อเนื่องที่เข้าใจง่ายซึ่งตอนนี้เราสามารถใช้เพื่อแสดงสิ่งที่เกิดขึ้น ...
มิติแรกเหมือนกับสมุดงาน Excel 2 แผ่นส่วนข้อมูลที่สองเหมือนกับแผ่นงาน 3 แผ่นในสมุดงานแต่ละมิติส่วนที่สามนั้นมี 4 แถวต่อแผ่นและมิติสุดท้ายคือ 5 ค่าสำหรับแต่ละแถว (หรือคอลัมน์ต่อแผ่น)
เมื่อมองด้วยวิธีนี้การถามx[0,:,:,0]
คือการพูดว่า: "ในเวิร์กบุ๊กแรกสำหรับแต่ละแผ่นสำหรับแต่ละแถวให้ค่า / คอลัมน์แรกให้ฉัน"
x[0,:,:,y[0]]
# returns:
array([[ 0, 5, 10, 15],
[20, 25, 30, 35],
[40, 45, 50, 55]])
# this is in the same as the first element in:
x[(0,0,0),:,:,y]
แต่ตอนนี้มีการจัดทำดัชนีขั้นสูงเราสามารถคิดว่าx[(0,0,0),:,:,y]
"ในเวิร์กบุ๊กแรกสำหรับแต่ละแผ่นสำหรับแต่ละแถวให้ฉันy
ค่า th / คอลัมน์ฉันตกลงตอนนี้ทำมันสำหรับแต่ละค่าของy
"
x[(0,0,0),:,:,y]
# returns:
array([[[ 0, 5, 10, 15],
[20, 25, 30, 35],
[40, 45, 50, 55]],
[[ 2, 7, 12, 17],
[22, 27, 32, 37],
[42, 47, 52, 57]],
[[ 4, 9, 14, 19],
[24, 29, 34, 39],
[44, 49, 54, 59]]])
ที่ใดที่มันคลั่งไคล้ก็คือคนอ้วนจะออกอากาศเพื่อจับคู่มิติด้านนอกของดัชนีอาเรย์ ดังนั้นหากคุณต้องการดำเนินการเช่นเดียวกับข้างต้น แต่สำหรับทั้ง "สมุดงาน Excel" คุณไม่จำเป็นต้องวนซ้ำและเรียงต่อกัน คุณสามารถส่งผ่านอาร์เรย์ไปยังมิติแรก แต่ต้องมีรูปร่างที่เข้ากันได้
y.shape == (3,)
ผ่านจำนวนเต็มได้รับการถ่ายทอดไปยัง y.shape
หากคุณต้องการที่จะผ่านอาร์เรย์เป็นดัชนีแรกเพียงมิติสุดท้ายของอาร์เรย์จะต้องมีความเข้ากันได้กับ คือมิติสุดท้ายของดัชนีแรกจะต้องเป็น 3 หรือ 1
ix = np.array([[0], [1]])
x[ix,:,:,y].shape
# each row of ix is broadcast to length 3:
(2, 3, 3, 4)
ix = np.array([[0,0,0], [1,1,1]])
x[ix,:,:,y].shape
# this is identical to above:
(2, 3, 3, 4)
ix = np.array([[0], [1], [0], [1], [0]])
x[ix,:,:,y].shape
# ix is broadcast so each row of ix has 3 columns, the length of y
(5, 3, 3, 4)
พบคำอธิบายสั้น ๆ ในเอกสาร: https://docs.scipy.org/doc/numpy/reference/arrays.indexing.html#combining-advanced-and-basic-indexing
แก้ไข:
จากคำถามเดิมเพื่อรับซับไลน์หนึ่งรายการที่ต้องการคุณสามารถใช้x[0][:,:,y]
:
x[0][:,:,y].shape
# returns
(2, 50, 3)
อย่างไรก็ตามหากคุณพยายามกำหนดให้กับส่วนย่อยเหล่านั้นคุณจะต้องระมัดระวังเป็นอย่างยิ่งว่าคุณกำลังดูมุมมองหน่วยความจำที่แชร์ของอาร์เรย์ดั้งเดิม มิฉะนั้นการมอบหมายจะไม่อยู่ในอาร์เรย์เดิม แต่เป็นสำเนา
หน่วยความจำที่ใช้ร่วมกันเกิดขึ้นเฉพาะเมื่อคุณกำลังใช้จำนวนเต็มหรือชิ้นไปยังระบบย่อยอาร์เรย์เช่นของคุณหรือ x[:,0:3,:,:]
x[0,:,:,1:-1]
np.shares_memory(x, x[0])
# returns:
True
np.shares_memory(x, x[:,:,:,y])
# returns:
False
ทั้งคำถามดั้งเดิมของคุณและตัวอย่างของฉันy
ไม่ใช่ทั้ง int หรือ slice ดังนั้นจะสิ้นสุดการกำหนดให้กับสำเนาต้นฉบับเสมอ
แต่! เนื่องจากอาร์เรย์ของคุณy
สามารถถูกแสดงเป็นส่วนย่อยคุณจึงสามารถรับมุมมองที่กำหนดได้ของอาร์เรย์ของคุณผ่าน:
x[0,:,:,0:21:10].shape
# returns:
(2, 50, 3)
np.shares_memory(x, x[0,:,:,0:21:10])
# returns:
True
# actually assigns to the original array
x[0,:,:,0:21:10] = 100
ที่นี่เราใช้ส่วนแบ่ง0:21:10
เพื่อจับทุกดัชนีที่จะเข้าrange(0,21,10)
มา เราต้องใช้21
และไม่ใช่20
เพราะจุดหยุดถูกแยกออกจากส่วนแบ่งเช่นเดียวกับในrange
ฟังก์ชั่น
ดังนั้นโดยทั่วไปถ้าคุณสามารถสร้างชิ้นที่เหมาะกับเกณฑ์ย่อยของคุณคุณสามารถมอบหมาย