numpy dizisindeki satırları silme


90

Şuna benzeyen bir dizim var:

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

Satırlardan birinin sonunda sıfır değerinin olduğuna dikkat edin. Tüm hücrelerde sıfır olmayan değerler içeren herhangi bir satırı tutarken sıfır içeren herhangi bir satırı silmek istiyorum.

Ancak dizi her doldurulduğunda farklı sayıda satıra sahip olacak ve sıfırlar her seferinde farklı satırlarda yer alacaktır.

Her satırdaki sıfır olmayan elemanların sayısını aşağıdaki kod satırıyla alıyorum:

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

Yukarıdaki dizi için NumNonzeroElementsInRowsşunları içerir: [5 4]

Beş, satır 0'daki olası tüm değerlerin sıfır olmadığını belirtirken, dört, satır 1'deki olası değerlerden birinin sıfır olduğunu belirtir.

Bu nedenle, sıfır değerleri içeren satırları bulmak ve silmek için aşağıdaki kod satırlarını kullanmaya çalışıyorum.

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

Ancak bazı nedenlerden dolayı, bu kod hiçbir şey yapmıyor gibi görünse de, çok sayıda yazdırma komutu yapmak, tüm değişkenlerin koda doğru doğru şekilde doldurulduğunu gösteriyor.

"Sıfır değeri içeren herhangi bir satırı silmenin" basit bir yolu olmalıdır.

Bunu başarmak için bana hangi kodu yazmam gerektiğini kimse gösterebilir mi?

Yanıtlar:


166

Dizilerden satırları ve sütunları silmenin en basit yolu numpy.deleteyöntemdir.

Aşağıdaki diziye sahip olduğumu varsayalım x:

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

İlk satırı silmek için şunu yapın:

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

Üçüncü sütunu silmek için şunu yapın:

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

Böylece, içinde 0 olan satırların indislerini bulabilir, onları bir listeye veya bir demete koyabilir ve bunu fonksiyonun ikinci argümanı olarak iletebilirsiniz.


Teşekkürler! Aynı sorunu yaşadım ve neden basitçe aramanın numpy.delete(x, index)işe yaramadığını anlayamadım.
Antimony

6
O notu docs) (silme numpy bir örnek bağlantı altında sağlanır - döndürülür yeni dizisi beri "Genellikle bir boolean maske kullanılması tercih edilir" ibaresi
arturomp

1
@arturomp ancak maske tahribatsız Silme çağrısı () zamanı / belleği mi tüketiyor?
Nathan

14

İşte bir satır (evet, user333700'lere benziyor, ancak biraz daha basit):

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

Bu arada, bu yöntem, büyük matrisler için maskelenmiş dizi yönteminden çok çok daha hızlıdır. 2048 x 5 matris için bu yöntem yaklaşık 1000 kat daha hızlıdır.

Bu arada, user333700'ün yöntemi (onun yorumundan) testlerimde biraz daha hızlıydı, ancak nedenini aklımı karıştırıyor.


3
"herhangi biri" kısa devre yapabilir, ilk gerçek durum tespit edilir edilmez, "tümü" tüm koşulları kontrol etmek zorunda iken, durabilir. Yani, herhangi bir ("~") değil, genel olarak hepsinden daha hızlı olmalıdır.
Josef

4
@ user333700, ikisi de sadece farklı şeylere kısa devre yapabilir. anytespit edilen ilk gerçek durumda kısa devreler doğruya; alltespit edilen ilk yanlış durumda kısa devreler yanlış olarak. Bu durumda, kısa devre berabere olmalı, ancak fazladan yapmak bence onu yavaşlatmamalı.
Justin Peel

5

Bu, orijinal yaklaşımınıza benzer ve unutbu'nun cevabından daha az yer kullanacaktır , ancak daha yavaş olacağını sanıyorum.

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

Bu arada, satırın p.delete()benim için çalışmıyor - ndarrays bir .deleteniteliğe sahip değil .


8
biraz daha basit: p [~ (p == 0) .any (1)] veya satırlar için daha açık: p [~ (p == 0) .any (1),:]
Josef

2

numpy aynı şeyi yapmak için basit bir işlev sağlar: maskelenmiş bir 'a' dizisine sahip olduğunuzu varsayarsak, numpy.ma.compress_rows (a) 'yı çağırmak maskelenmiş bir değer içeren satırları siler. Sanırım bu şekilde çok daha hızlı ...


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

Bu soruyu cevaplamak için çok geç kalmış olabilirim, ancak topluluğun yararı için girdimi paylaşmak istedim. Bu örnek için, matrisinize 'ANOVA' diyeyim ve bu matristen yalnızca 5. sütunda 0 olan satırları kaldırmaya çalıştığınızı varsayıyorum.

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]
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.