2010-10-06 54 views
49

Tôi có một mảng mà có thể trông như thế này:hàng xóa trong mảng NumPy

ANOVAInputMatrixValuesArray = [[ 0.96488889, 0.73641667, 0.67521429, 0.592875, 
0.53172222], [ 0.78008333, 0.5938125, 0.481, 0.39883333, 0.]] 

Chú ý rằng một trong những hàng có giá trị zero ở cuối. Tôi muốn xóa bất kỳ hàng nào có chứa số không, trong khi vẫn giữ bất kỳ hàng nào chứa các giá trị khác 0 trong tất cả các ô.

Nhưng mảng sẽ có số hàng khác nhau mỗi khi được điền và số 0 sẽ được đặt ở các hàng khác nhau mỗi lần.

tôi nhận được số phần tử khác không trong mỗi hàng với dòng mã sau đây:

NumNonzeroElementsInRows = (ANOVAInputMatrixValuesArray != 0).sum(1) 

Đối với các mảng trên, NumNonzeroElementsInRows chứa: [5 4]

Năm chỉ ra rằng tất cả các giá trị có thể có trong hàng 0 đều là nonzero, trong khi bốn giá trị chỉ ra rằng một trong các giá trị có thể có trong hàng 1 là số không.

Vì vậy, tôi đang cố gắng sử dụng các dòng mã sau đây để tìm và xóa các hàng có chứa giá trị bằng không.

for q in range(len(NumNonzeroElementsInRows)): 
    if NumNonzeroElementsInRows[q] < NumNonzeroElementsInRows.max(): 
     p.delete(ANOVAInputMatrixValuesArray, q, axis=0) 

Nhưng vì lý do nào đó, mã này dường như không làm gì cả, mặc dù thực hiện nhiều lệnh in cho biết tất cả các biến dường như được điền chính xác vào mã.

Phải có một số cách dễ dàng để chỉ đơn giản là "xóa mọi hàng có chứa giá trị bằng 0".

Có ai có thể cho tôi biết mã nào cần viết để thực hiện việc này không?

Trả lời

4

Điều này tương tự như cách tiếp cận ban đầu của bạn và sẽ sử dụng ít không gian hơn unutbu's answer, nhưng tôi nghi ngờ nó sẽ chậm hơn.

>>> import numpy as np 
>>> p = np.array([[1.5, 0], [1.4,1.5], [1.6, 0], [1.7, 1.8]]) 
>>> p 
array([[ 1.5, 0. ], 
     [ 1.4, 1.5], 
     [ 1.6, 0. ], 
     [ 1.7, 1.8]]) 
>>> nz = (p == 0).sum(1) 
>>> q = p[nz == 0, :] 
>>> q 
array([[ 1.4, 1.5], 
     [ 1.7, 1.8]]) 

Bằng cách này, dòng của bạn p.delete() không làm việc cho tôi - ndarray s không có một thuộc tính .delete.

+8

một chút đơn giản hơn: p [~ (p == 0) Bất cứ (1)] hoặc rõ ràng hơn cho các hàng: p [~ (p == 0) Bất cứ (1),:] – user333700

+0

@ user333700 - Đó phải là câu trả lời - bạn chắc chắn sẽ nhận được phiếu bầu của tôi! 'any' rõ ràng hơn' sum' trong việc sử dụng này. – mtrw

12

Dưới đây là một lót (có, nó cũng tương tự như của user333700, nhưng một chút đơn giản hơn):

>>> import numpy as np 
>>> arr = np.array([[ 0.96488889, 0.73641667, 0.67521429, 0.592875, 0.53172222], 
       [ 0.78008333, 0.5938125, 0.481, 0.39883333, 0.]]) 
>>> print arr[arr.all(1)] 
array([[ 0.96488889, 0.73641667, 0.67521429, 0.592875 , 0.53172222]]) 

Bằng cách này, phương pháp này là nhiều, nhanh hơn nhiều so với phương pháp mảng đeo mặt nạ cho ma trận lớn . Đối với ma trận 2048 x 5, phương pháp này nhanh hơn khoảng 1000 lần.

Nhân tiện, phương pháp của người dùng333700 (từ nhận xét của ông) nhanh hơn một chút trong các thử nghiệm của tôi, mặc dù nó phản ánh tâm trí của tôi tại sao.

+3

"bất kỳ" có thể ngắn mạch, ngay sau khi trường hợp thực sự đầu tiên được phát hiện, nó có thể dừng lại, trong khi "tất cả" phải kiểm tra tất cả các điều kiện. Vì vậy, không phải ("~" trong numpy) bất kỳ, nên nói chung là nhanh hơn tất cả. – user333700

+3

@ user333700, cả hai đều có thể ngắn mạch, chỉ với những thứ khác nhau. 'bất kỳ' ngắn mạch đến đúng tại trường hợp thực sự đầu tiên được phát hiện; 'tất cả' ngắn mạch để sai tại trường hợp sai đầu tiên được phát hiện. Trong trường hợp này, ngắn mạch nên là một trận hòa, nhưng làm thêm không nên làm cho nó chậm hơn trong quan điểm của tôi. –

2

numpy cung cấp chức năng đơn giản để thực hiện cùng một điều: giả sử bạn có mảng bị che chắn 'a', gọi numpy.ma.compress_rows (a) sẽ xóa các hàng chứa giá trị được che. Tôi đoán điều này nhanh hơn nhiều theo cách này ...

96

Cách đơn giản nhất để xóa hàng và cột khỏi mảng là phương pháp numpy.delete.

Giả sử tôi có các mảng sau x:

x = array([[1,2,3], 
     [4,5,6], 
     [7,8,9]]) 

Để xóa hàng đầu tiên, làm như sau:

x = numpy.delete(x, (0), axis=0) 

Để xóa cột thứ ba, làm như sau:

x = numpy.delete(x,(2), axis=1) 

Vì vậy, bạn có thể tìm thấy các chỉ số của các hàng có 0 trong chúng, đặt chúng vào một danh sách hoặc một bộ tuple và chuyển nó thành đối số thứ hai của hàm.

+0

Cảm ơn! Tôi đã có cùng một vấn đề, và tôi không thể hiểu tại sao chỉ đơn giản gọi 'numpy.delete (x, index)' không hoạt động. – Antimony

+3

lưu ý rằng tài liệu [numpy delete() docs] (https://docs.scipy.org/doc/numpy/reference/generated/numpy.delete.html) cho biết rằng "Thường thì bạn nên sử dụng mặt nạ boolean" vì một mảng mới được trả về - một ví dụ được cung cấp dưới liên kết đó – arturomp

0

Tôi có thể đã quá muộn để trả lời câu hỏi này, nhưng tôi muốn chia sẻ ý kiến ​​đóng góp của tôi vì lợi ích của cộng đồng. Đối với ví dụ này, hãy để tôi gọi ma trận của bạn 'ANOVA', và tôi giả sử bạn chỉ đang cố gắng để loại bỏ các hàng từ ma trận này với 0 chỉ trong cột thứ 5.

indx = [] 
for i in range(len(ANOVA)): 
    if int(ANOVA[i,4]) == int(0): 
     indx.append(i) 

ANOVA = [x for x in ANOVA if not x in indx]