2016-01-09 16 views
5

Tôi có một mảng numpy và một danh sách các giá trị hợp lệ trong mảng rằng:Làm cách nào để đặt giá trị ô trong `np.array()` dựa trên điều kiện?

import numpy as np 
arr = np.array([[1,2,0], [2,2,0], [4,1,0], [4,1,0], [3,2,0], ... ]) 
valid = [1,4] 

Có cách nào pythonic tốt đẹp để đặt tất cả các giá trị mảng bằng không, mà không phải là trong danh sách các giá trị hợp lệ và làm điều đó tại chỗ? Sau hoạt động này, danh sách sẽ trông như thế này:

   [[1,0,0], [0,0,0], [4,1,0], [4,1,0], [0,0,0], ... ] 

Sau đây tạo một bản sao của mảng trong bộ nhớ, mà có hại cho mảng lớn:

arr = np.vectorize(lambda x: x if x in valid else 0)(arr) 

Nó làm tôi phát cáu, mà bây giờ tôi lặp qua mỗi phần tử mảng và đặt nó thành 0 nếu nó nằm trong danh sách valid.

Chỉnh sửa: Tôi tìm thấy một answer cho thấy không có chức năng tại chỗ để đạt được điều này. Cũng ngừng thay đổi khoảng trắng của tôi. Thật dễ dàng để xem các thay đổi trong số arr với chúng.

Trả lời

3

Bạn có thể sử dụng np.place cho một bản cập nhật in-situ -

np.place(arr,~np.in1d(arr,valid),0) 

mẫu chạy -

In [66]: arr 
Out[66]: 
array([[1, 2, 0], 
     [2, 2, 0], 
     [4, 1, 0], 
     [4, 1, 0], 
     [3, 2, 0]]) 

In [67]: np.place(arr,~np.in1d(arr,valid),0) 

In [68]: arr 
Out[68]: 
array([[1, 0, 0], 
     [0, 0, 0], 
     [4, 1, 0], 
     [4, 1, 0], 
     [0, 0, 0]]) 

Dọc theo đường cùng, np.put cũng có thể được sử dụng -

np.put(arr,np.where(~np.in1d(arr,valid))[0],0) 

mẫu chạy -

In [70]: arr 
Out[70]: 
array([[1, 2, 0], 
     [2, 2, 0], 
     [4, 1, 0], 
     [4, 1, 0], 
     [3, 2, 0]]) 

In [71]: np.put(arr,np.where(~np.in1d(arr,valid))[0],0) 

In [72]: arr 
Out[72]: 
array([[1, 0, 0], 
     [0, 0, 0], 
     [4, 1, 0], 
     [4, 1, 0], 
     [0, 0, 0]]) 
+1

Tôi nghi ngờ rằng sẽ tạo ra một bản sao tạm thời cũng kể từ khi bạn định hình lại một mảng và nhân nó bằng cách ban đầu của nó. Vì vậy, nó không yêu cầu "tại chỗ" của tôi. Bạn có thể thấy điều này bằng cách gõ 'arr' sau thao tác. Nó vẫn cung cấp cho bạn các mảng ban đầu với twos và threes. –

+0

Bạn thực sự chỉ cần thực hiện một câu trả lời mới thay vì chỉnh sửa câu trả lời cũ của bạn hơn và hơn. Nó làm cho cuộc thảo luận trở nên khó khăn. Với 'np.place (arr, ~ np.in1d ​​(arr, valid), 0)' phần 'in1d' vẫn tạo ra một bản sao bộ nhớ của toàn bộ mảng, cùng với' np.put (arr, np.where (~ np.in1d ​​(arr, hợp lệ)) [0], 0) '. –

+0

@ con-f-use Như tôi đã hiểu, '~ np.in1d ​​(arr, hợp lệ)' sẽ là một mảng boolean và như vậy sẽ chiếm ít bộ nhớ hơn một mảng số nguyên điển hình, sửa tôi nếu tôi sai ở đây. Và sau đó nó cập nhật tại chỗ trong 'arr', vì vậy không có bản sao nào khác có liên quan ở đó. – Divakar

1

Indexing với các phép toán luận sẽ làm việc quá:

>>> arr = np.array([[1, 2, 0], [2, 2, 0], [4, 1, 0], [4, 1, 0], [3, 2, 0]]) 
>>> arr[~np.in1d(arr, valid).reshape(arr.shape)] = 0 
>>> arr 
array([[1, 0, 0], 
     [0, 0, 0], 
     [4, 1, 0], 
     [4, 1, 0], 
     [0, 0, 0]]) 
Các vấn đề liên quan