xóa các hàng trong mảng numpy


88

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

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

Lưu ý rằng một trong các hàng có giá trị 0 ở cuối. Tôi muốn xóa bất kỳ hàng nào có chứa số 0, 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ố lượng hàng khác nhau mỗi khi nó được điền và các số không sẽ nằm ở các hàng khác nhau mỗi lần.

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

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

Đối với mảng ở trên, NumNonzeroElementsInRowschứa: [5 4]

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

Do đó, tôi đang cố gắng sử dụng các dòng mã sau để tìm và xóa các hàng 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 đó, đoạn mã này dường như không thực hiện được gì, mặc dù thực hiện rất nhiều lệnh in cho thấy rằng tất cả các biến dường như đang được điền chính xác dẫn đến mã.

Phải có một số cách dễ dàng để chỉ cần "xóa bất kỳ hàng nào chứa giá trị bằng không."

Bất cứ ai có thể chỉ cho tôi những gì mã để viết để thực hiện điều này?

Câu trả lời:


162

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

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

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

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

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

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

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

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


Cảm ơn! Tôi đã gặp vấn đề tương tự và tôi không thể hiểu tại sao chỉ đơn giản là gọi điện numpy.delete(x, index)lại không hoạt động.
Antimony

6
lưu ý rằng NumPy xóa () tài liệu chỉ ra rằng "Thường thì nó là thích hợp hơn để sử dụng một mặt nạ boolean" từ một mảng mới được trả lại - một ví dụ được cung cấp dưới liên kết
arturomp

1
@arturomp nhưng mặt nạ không phá hủy. Một cuộc gọi để xóa () có tốn thời gian / bộ nhớ không?
Nathan

13

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

>>> 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]])

Nhân tiện, phương thức này nhanh hơn rất nhiều so với phương pháp mảng được che 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 user333700 (từ nhận xét của anh ấy) nhanh hơn một chút trong các thử nghiệm của tôi, mặc dù nó làm tôi bối rối tại sao.


3
"any" có thể ngắn mạch, ngay sau khi trường hợp đúng đầu tiên được phát hiện, nó có thể dừng lại, trong khi "all" 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ói chung phải nhanh hơn tất cả.
Josef,

4
@ user333700, cả hai đều có thể đoản mạch, chỉ là những thứ khác nhau. anyđoản mạch thành true ở trường hợp true đầu tiên được phát hiện; allđoản mạch thành sai ở trường hợp sai đầu tiên được phát hiện. Trong trường hợp này, việc đoản mạch sẽ là một kết quả hòa, nhưng theo tôi, làm thêm thì không nên làm cho nó chậm hơn.
Justin Peel

5

Đ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 dung lượng hơn câu trả lời của unutbu , 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]])

Nhân tiện, dòng của bạn p.delete()không phù hợp với tôi - ndarraykhông có .deletethuộc tính.


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),:]
Josef

2

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


1
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[np.where(arr != 0.)])

-1

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 mình 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 là 'ANOVA', và tôi giả sử bạn chỉ đang cố gắng xóa các hàng khỏi ma trận này với số 0 chỉ ở 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]
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.