Pandalar veri çerçevesinde tamamı sıfır olan satırları bırak


110

pandas dropna()Bazı veya tüm sütunların NA's olarak ayarlandığı satırları kaldırmak için işlevselliği kullanabilirim . Tüm sütunların 0 değerine sahip olduğu satırları bırakmak için eşdeğer bir işlev var mı?

P   kt  b   tt  mky depth
1   0   0   0   0   0
2   0   0   0   0   0
3   0   0   0   0   0
4   0   0   0   0   0
5   1.1 3   4.5 2.3 9.0

Bu örnekte, ilk 4 satırı veri çerçevesinden çıkarmak istiyoruz.

Teşekkürler!


Sadece açıklığa kavuşturmak için, bu iki soru. Bir, tüm değerleri 0 olan sütunları bırakmak için. Ama aynı zamanda, dropna () 'ya eşdeğer bir işlev için, herhangi bir değeri 0 olan sütunları düşürür.
simya

Yanıtlar:


120

Bunun vektörleştirilmiş bir şekilde güzel bir şekilde ifade edilebileceği ortaya çıktı:

> df = pd.DataFrame({'a':[0,0,1,1], 'b':[0,1,0,1]})
> df = df[(df.T != 0).any()]
> df
   a  b
1  0  1
2  1  0
3  1  1

7
Güzel, ama olumsuzluklardan kaçınabileceğinizi düşünüyorumdf = df[(df.T != 0).any()]
Akavall

1
@Akavall Çok daha iyi!
U2EF1

1
Sadece bir not: OP bırakmak istedi rows with all columns having value 0, ancak biri allyöntem çıkarabilir .
paulochf

1
Tüm bu cevaplar, satırları nasıl tamamen sıfırlarla bırakabileceğimizi açıklıyor, Ancak, ilk sütunda 0 olan satırları bırakmak istedim. Bu gönderideki tüm tartışma ve yanıtların yardımıyla bunu df.loc [df.iloc [:, 0]! = 0] yaparak yaptım. Sadece paylaşmak istedim çünkü bu sorun bu soruyla ilgili !!
hemanta

2
Transpoze gerekli değildir, herhangi bir () ekseni parametre olarak alabilir. Bu işe yarıyor: df = df [df.any (axis = 1)]
Rahul Jha

138

Tek satırlık. Transpoze gerek yok:

df.loc[~(df==0).all(axis=1)]

Ve simetriyi sevenler için bu da işe yarar ...

df.loc[(df!=0).any(axis=1)]

1
Kısa olması için (ve, bence, amacın netliği) bu ve Akavall yorumuna birleştirir: df.loc[(df != 0).any(1)]. Takım çalışması!
Dan Allan

1
+1,% 30 daha hızlı transpoze - 491'den 614'e mikrosaniye ve axis=1açık olduğu için seviyorum ; bence daha fazla
pitonik

Orijinal soru dropna'nın denkliğinden bahsettiğinden, .all ve .any arasındaki farklardan bahsedilmelidir. Sıfır içeren herhangi bir sütuna sahip tüm satırları bırakmak isterseniz, yukarıdaki cevapta .all ve .any'yi tersine çevirmelisiniz. Bu işlevselliği ararken bunu fark etmem biraz zaman aldı.
Zak Keirn

Bu benim için işe yaramıyor, ancak bana aynı şeyi döndürüyordf
Robvh

Bunun "yerinde" bir versiyonu var mı? Bunun olması gerekir, OP istendiği gibi bir df satırları düşmesi bkz df = df.loc[(df!=0).all(axis=1)]ve df = df.loc[(df!=0).any(axis=1)]dropna gerçek eşdeğer olacak şekilde () Herhangi sıfırlarla satırları düşmesi.
simya

20

Bu soruyu yaklaşık ayda bir ararım ve her zaman yorumlardan en iyi yanıtı çıkarmam gerekir:

df.loc[(df!=0).any(1)]

Teşekkürler Dan Allan!


2
Kazmaya gerek yok. @ 8one6 bunu 2014 yılında kendi cevabına dahil etti, "Ve simetriyi sevenler için ..." yazan bölüm.
Rahul Murmuria

17

Sıfırları ile değiştirin nanve ardından tüm girişleri içeren satırları olarak bırakın nan. Bundan sonra nansıfırlarla değiştirin .

import numpy as np
df = df.replace(0, np.nan)
df = df.dropna(how='all', axis=0)
df = df.replace(np.nan, 0)

6
Verilerinizde önceden var olan NaN'leriniz varsa bu başarısız olur.
OmerB


7

Bunu ararken yardımcı olduğunu bulduğum birkaç çözüm, özellikle daha büyük veri kümeleri için:

df[(df.sum(axis=1) != 0)]       # 30% faster 
df[df.values.sum(axis=1) != 0]  # 3X faster 

@ U2EF1'deki örneğe devam ederek:

In [88]: df = pd.DataFrame({'a':[0,0,1,1], 'b':[0,1,0,1]})

In [91]: %timeit df[(df.T != 0).any()]
1000 loops, best of 3: 686 µs per loop

In [92]: df[(df.sum(axis=1) != 0)]
Out[92]: 
   a  b
1  0  1
2  1  0
3  1  1

In [95]: %timeit df[(df.sum(axis=1) != 0)]
1000 loops, best of 3: 495 µs per loop

In [96]: %timeit df[df.values.sum(axis=1) != 0]
1000 loops, best of 3: 217 µs per loop

Daha büyük bir veri kümesinde:

In [119]: bdf = pd.DataFrame(np.random.randint(0,2,size=(10000,4)))

In [120]: %timeit bdf[(bdf.T != 0).any()]
1000 loops, best of 3: 1.63 ms per loop

In [121]: %timeit bdf[(bdf.sum(axis=1) != 0)]
1000 loops, best of 3: 1.09 ms per loop

In [122]: %timeit bdf[bdf.values.sum(axis=1) != 0]
1000 loops, best of 3: 517 µs per loop

Satırınız -1 ve 1 içeriyorsa kötü şeyler olur mu?
Rhys Ulerich

: Elbette, toplamının, eşit satırları Burada biraz daha yavaş sadece bunun için hızlı bir çözüm var 0'a kadar ekleyerek olsaydı işe yaramaz df[~(df.values.prod(axis=1) == 0) | ~(df.values.sum(axis=1)==0)]
Clocker

Prod () işlevi hiçbir şeyi çözmez. Satırda 0 döndüren herhangi bir 0 varsa, şu şekilde bir satırı işlemeniz gerekiyorsa: [-1, -0.5, 0, 0.5, 1], çözümleriniz hiçbiri çalışmayacaktır.
Rahul Murmuria

İşte kabul edilen cevaptan 3 kat daha hızlı çalışan doğru bir versiyon:bdf[np.square(bdf.values).sum(axis=1) != 0]
Rahul Murmuria

5
import pandas as pd

df = pd.DataFrame({'a' : [0,0,1], 'b' : [0,0,-1]})

temp = df.abs().sum(axis=1) == 0      
df = df.drop(temp)

Sonuç:

>>> df
   a  b
2  1 -1

1 sütunlu veri çerçevesiyle benim için çalışmadı. GotValueError: labels [True ... ] not contained in matrix
The Unfun Cat

df = df.drop(temp)kullanım yerinedf = df.drop(df[temp].index)
Douglas Ferreira

3

lambdaBelirli bir satırdaki tüm değerlerin olup olmadığını kontrol etmek için hızlı bir işlevi kullanabilirsiniz 0. Ardından, bunu uygulamanın sonucunu lambdayalnızca bu koşulla eşleşen veya eşleşmeyen satırları seçmenin bir yolu olarak kullanabilirsiniz:

import pandas as pd
import numpy as np

np.random.seed(0)

df = pd.DataFrame(np.random.randn(5,3), 
                  index=['one', 'two', 'three', 'four', 'five'],
                  columns=list('abc'))

df.loc[['one', 'three']] = 0

print df
print df.loc[~df.apply(lambda row: (row==0).all(), axis=1)]

Getiri:

              a         b         c
one    0.000000  0.000000  0.000000
two    2.240893  1.867558 -0.977278
three  0.000000  0.000000  0.000000
four   0.410599  0.144044  1.454274
five   0.761038  0.121675  0.443863

[5 rows x 3 columns]
             a         b         c
two   2.240893  1.867558 -0.977278
four  0.410599  0.144044  1.454274
five  0.761038  0.121675  0.443863

[3 rows x 3 columns]

1

Başka bir alternatif:

# Is there anything in this row non-zero?
# df != 0 --> which entries are non-zero? T/F
# (df != 0).any(axis=1) --> are there 'any' entries non-zero row-wise? T/F of rows that return true to this statement.
# df.loc[all_zero_mask,:] --> mask your rows to only show the rows which contained a non-zero entry.
# df.shape to confirm a subset.

all_zero_mask=(df != 0).any(axis=1) # Is there anything in this row non-zero?
df.loc[all_zero_mask,:].shape


0

Benim için bu kod: df.loc[(df!=0).any(axis=0)] işe yaramadı. Kesin veri kümesini döndürdü.

Bunun yerine, df.loc[:, (df!=0).any(axis=0)]veri kümesindeki 0 değerli tüm sütunları kullandım ve bıraktım

İşlev, veri .all()kümemdeki sıfır değerleri olan tüm sütunları bıraktı.


-1
df = df [~( df [ ['kt'  'b'   'tt'  'mky' 'depth', ] ] == 0).all(axis=1) ]

Bu komutu mükemmel şekilde çalıştığını deneyin.


-2

Herhangi bir satırda 0 değerine sahip tüm sütunları bırakmak için:

new_df = df[df.loc[:]!=0].dropna()
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.