Hiểu về numpy.where
Tôi muốn nhận chỉ mục đầu tiên của phần tử mảng numpy lớn hơn một số phần tử cụ thể của cùng một mảng đó. Tôi đã thử làm theo:
>>> Q5=[[1,2,3],[4,5,6]]
>>> Q5 = np.array(Q5)
>>> Q5[0][Q5>Q5[0,0]]
array([2, 3])
>>> np.where(Q5[0]>Q5[0,0])
(array([1, 2], dtype=int32),)
>>> np.where(Q5[0]>Q5[0,0])[0][0]
1
Q1. Ở trên có đúng cách để có được chỉ số đầu tiên của một phần tử Q5[0]lớn hơn Q5[0,0]không?
Tôi quan tâm nhiều hơn đến việc np.where(Q5[0]>Q5[0,0])trả về tuple (array([1, 2], dtype=int32),)và do đó yêu cầu tôi phải nhân đôi chỉ mục [0][0]ở cuối np.where(Q5[0]>Q5[0,0])[0][0].
Quý 2. Tại sao lại trả về tuple này, nhưng bên dưới trả về mảng numpy thích hợp?
>>> np.where(Q5[0]>Q5[0,0],Q5[0],-1)
array([-1, 2, 3])
Để tôi có thể lập chỉ mục trực tiếp:
>>> np.where(Q5[0]>Q5[0,0],Q5[0],-1)[1]
2
Trả lời
In [58]: A = np.arange(1,10).reshape(3,3)
In [59]: A.shape
Out[59]: (3, 3)
In [60]: A
Out[60]:
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
np.wherechỉ với điều kiện là thực sự np.nonzero.
Tạo một mảng boolean:
In [63]: A==6
Out[63]:
array([[False, False, False],
[False, False, True],
[False, False, False]])
Tìm nơi điều đó là đúng:
In [64]: np.nonzero(A==6)
Out[64]: (array([1]), array([2]))
Kết quả là một bộ giá trị, một phần tử trên mỗi chiều của điều kiện. Mỗi phần tử là một mảng lập chỉ mục, chúng cùng nhau xác định vị trí của (các) True
Một thử nghiệm khác với một số True
In [65]: (A%3)==1
Out[65]:
array([[ True, False, False],
[ True, False, False],
[ True, False, False]])
In [66]: np.nonzero((A%3)==1)
Out[66]: (array([0, 1, 2]), array([0, 0, 0]))
Sử dụng bộ tuple để lập chỉ mục mảng ban đầu:
In [67]: A[np.nonzero((A%3)==1)]
Out[67]: array([1, 4, 7])
Sử dụng đối số 3 wheređể tạo một mảng mới với kết hợp các giá trị từ AvàA+10
In [68]: np.where((A%3)==1,A+10, A)
Out[68]:
array([[11, 2, 3],
[14, 5, 6],
[17, 8, 9]])
Nếu điều kiện có nhiều True, nonzerokhông phải là công cụ kiểm tra để tìm "đầu tiên", vì nó nhất thiết phải tìm tất cả.
Bộ giá trị khác không có thể được chuyển thành mảng 2d với a transpose. Thực sự có thể dễ dàng hơn để lấy "đầu tiên" từ mảng này:
In [73]: np.argwhere((A%3)==1)
Out[73]:
array([[0, 0],
[1, 0],
[2, 0]])
Bạn đang tìm kiếm trong một mảng 1d, một hàng A:
In [77]: A[0]>A[0,0]
Out[77]: array([False, True, True])
In [78]: np.nonzero(A[0]>A[0,0])
Out[78]: (array([1, 2]),) # 1 element tuple
In [79]: np.argwhere(A[0]>A[0,0])
Out[79]:
array([[1],
[2]])
In [81]: np.where(A[0]>A[0,0], 100, 0) # 3 argument where
Out[81]: array([ 0, 100, 100])
Vì vậy, cho dù bạn đang tìm kiếm mảng 1d hay 2d (hoặc 3 hoặc 4), nonzerotrả về một bộ giá trị với một phần tử mảng trên mỗi chiều. Bằng cách đó, nó luôn có thể được sử dụng để lập chỉ mục một mảng có kích thước tương tự. Bộ tuple 1d có thể trông thừa, nhưng nó phù hợp với các kết quả thứ nguyên khác.
Khi thử hiểu các thao tác như thế này, hãy đọc kỹ tài liệu và xem xét các bước riêng lẻ. Ở đây tôi xem xét ma trận điều kiện, nonzerokết quả và các cách sử dụng khác nhau của nó.
numpy.where () giống như một vòng lặp for với if.
numpy.where(condition, values, new_value)
điều kiện - giống như điều kiện nếu.
giá trị - Các giá trị để lặp lại trên
new_value - nếu điều kiện là đúng với một giá trị , nó sẽ thay đổi thành new_value
Nếu chúng ta muốn viết nó cho mảng 1 chiều, nó sẽ trông giống như sau:
[xv if c else yv
for c, xv, yv in zip(condition, x, y)]
Thí dụ:
>>> a = np.arange(10)
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> np.where(a < 5, a, 10*a)
array([ 0, 1, 2, 3, 4, 50, 60, 70, 80, 90])
Trước tiên, chúng tôi tạo một mảng với các số từ 0 đến 9 (0, 1, 2 ... 7, 8, 9)
và sau đó chúng tôi kiểm tra tất cả các giá trị trong mảng lớn hơn từ 5 và nhân giá trị của chúng với 10.
Vì vậy, bây giờ tất cả các giá trị trong mảng nhỏ hơn 5 được giữ nguyên và tất cả các giá trị lớn hơn nhân với 10
Sử dụng argmaxvới một mảng boolean sẽ cung cấp cho bạn chỉ số của True đầu tiên.
In [54]: q
Out[54]:
array([[1, 2, 3],
[4, 5, 6]])
In [55]: q > q[0,0]
Out[55]:
array([[False, True, True],
[ True, True, True]], dtype=bool)
argmax có thể lấy một đối số trục / kích thước.
In [56]: np.argmax(q > q[0,0], 0)
Out[56]: array([1, 0, 0], dtype=int64)
Điều đó nói rằng True đầu tiên là chỉ mục một cho cột 0 và chỉ mục 0 cho cột một và hai.
In [57]: np.argmax(q > q[0,0], 1)
Out[57]: array([1, 0], dtype=int64)
Điều đó nói rằng True đầu tiên là chỉ mục một cho hàng 0 và chỉ mục 0 cho hàng một.
Q1. Ở trên có đúng cách để có được chỉ số đầu tiên của một phần tử trong Q5 [0] lớn hơn Q5 [0,0] không?
Không, tôi sẽ sử dụng argmaxvới 1cho axisđối số, sau đó chọn mục đầu tiên từ kết quả đó.
Quý 2. Tại sao lại này tuple
Bạn đã yêu cầu nó trả về -1giá trị Sai và trả về Q5[0]các mục cho giá trị True.
Q2 ... nhưng bên dưới trả về mảng numpy thích hợp?
Bạn đã may mắn và chọn đúng chỉ số.