Pandalar DataFrame'den boş hücreler içeren satırları bırak


92

Bir var pd.DataFramebazı excel elektronik tablolar ayrıştırma tarafından oluşturulduğunu. Bir sütunda boş hücreler var. Örneğin, bu sütunun sıklığı için çıktı aşağıdadır, 32320 kayıt Kiracı için eksik değerlere sahiptir .

>>> value_counts(Tenant, normalize=False)
                              32320
    Thunderhead                8170
    Big Data Others            5700
    Cloud Cruiser              5700
    Partnerpedia               5700
    Comcast                    5700
    SDP                        5700
    Agora                      5700
    dtype: int64

Kiracı'nın eksik olduğu satırları bırakmaya çalışıyorum, ancak .isnull()seçenek eksik değerleri tanımıyor.

>>> df['Tenant'].isnull().sum()
    0

Sütunun veri türü "Nesne" vardır. Bu durumda ne oluyor? Kiracı'nın eksik olduğu kayıtları nasıl bırakabilirim ?

Yanıtlar:


179

Pandalar , DataFrame'deki np.nangibi yazdırılan bir nesne ise değeri boş olarak NaNtanıyacaktır. Eksik değerleriniz muhtemelen Pandaların boş olarak tanımadığı boş dizelerdir. Bunu düzeltmek için, boş sokmaları (veya boş hücrelerinizdeki her şeyi) kullanarak np.nannesnelere dönüştürebilir replace()ve ardından dropna()DataFrame'inizi boş kiracılarla satırları silmek için çağırabilirsiniz.

Göstermek için, bir sütunda bazı rastgele değerler ve bazı boş dizeler içeren bir DataFrame oluşturuyoruz Tenants:

>>> import pandas as pd
>>> import numpy as np
>>> 
>>> df = pd.DataFrame(np.random.randn(10, 2), columns=list('AB'))
>>> df['Tenant'] = np.random.choice(['Babar', 'Rataxes', ''], 10)
>>> print df

          A         B   Tenant
0 -0.588412 -1.179306    Babar
1 -0.008562  0.725239         
2  0.282146  0.421721  Rataxes
3  0.627611 -0.661126    Babar
4  0.805304 -0.834214         
5 -0.514568  1.890647    Babar
6 -1.188436  0.294792  Rataxes
7  1.471766 -0.267807    Babar
8 -1.730745  1.358165  Rataxes
9  0.066946  0.375640         

Şimdi Tenantssütundaki boş dizeleri şu şekilde np.nannesnelerle değiştiriyoruz :

>>> df['Tenant'].replace('', np.nan, inplace=True)
>>> print df

          A         B   Tenant
0 -0.588412 -1.179306    Babar
1 -0.008562  0.725239      NaN
2  0.282146  0.421721  Rataxes
3  0.627611 -0.661126    Babar
4  0.805304 -0.834214      NaN
5 -0.514568  1.890647    Babar
6 -1.188436  0.294792  Rataxes
7  1.471766 -0.267807    Babar
8 -1.730745  1.358165  Rataxes
9  0.066946  0.375640      NaN

Şimdi boş değerleri bırakabiliriz:

>>> df.dropna(subset=['Tenant'], inplace=True)
>>> print df

          A         B   Tenant
0 -0.588412 -1.179306    Babar
2  0.282146  0.421721  Rataxes
3  0.627611 -0.661126    Babar
5 -0.514568  1.890647    Babar
6 -1.188436  0.294792  Rataxes
7  1.471766 -0.267807    Babar
8 -1.730745  1.358165  Rataxes

Çok teşekkürler, bunu bir deneyeceğim ve geri döneceğim!
Amrita Sawant

2
@mcmath, biraz meraklı. Neden numpy'i içe aktarıyorsun ve np.nanyapabildiğin zaman kullanıyorsun pd.np.nan?
propjk007

3
@ propjk007, hayattaki pek çok şeyde olduğu gibi, birçok şeyi yapmanın birçok yolu vardır
andrew

Benim itibaren testlerde , bu yapıyor gibi görünüyor df[df['Tenant'].astype(bool)]olduğunu - (sadece boş bir dize hiçbir boşluk karakter varsayarak) hızlı dahadf.replace('', np.nan).dropna(subset=['Tenant'])
cs95

53

Pythonic + Pandorable: df[df['col'].astype(bool)]

Boş dizeler yanlıştır, yani bool değerlerini aşağıdaki gibi filtreleyebilirsiniz:

df = pd.DataFrame({
    'A': range(5),
    'B': ['foo', '', 'bar', '', 'xyz']
})
df
   A    B
0  0  foo
1  1     
2  2  bar
3  3     
4  4  xyz
df['B'].astype(bool)                                                                                                                      
0     True
1    False
2     True
3    False
4     True
Name: B, dtype: bool

df[df['B'].astype(bool)]                                                                                                                  
   A    B
0  0  foo
2  2  bar
4  4  xyz

Amacınız yalnızca boş dizeleri değil, aynı zamanda yalnızca boşluk içeren dizeleri de kaldırmaksa, str.stripönceden kullanın :

df[df['B'].str.strip().astype(bool)]
   A    B
0  0  foo
2  2  bar
4  4  xyz

Düşündüğünden daha hızlı

.astypevektörleştirilmiş bir işlemdir, bu şimdiye kadar sunulan her seçenekten daha hızlıdır. En azından testlerimden. YMMV.

İşte bir zamanlama karşılaştırması, aklıma gelen diğer bazı yöntemlere atmıştım.

görüntü açıklamasını buraya girin

Referans için kıyaslama kodu:

import pandas as pd
import perfplot

df1 = pd.DataFrame({
    'A': range(5),
    'B': ['foo', '', 'bar', '', 'xyz']
})

perfplot.show(
    setup=lambda n: pd.concat([df1] * n, ignore_index=True),
    kernels=[
        lambda df: df[df['B'].astype(bool)],
        lambda df: df[df['B'] != ''],
        lambda df: df[df['B'].replace('', np.nan).notna()],  # optimized 1-col
        lambda df: df.replace({'B': {'': np.nan}}).dropna(subset=['B']),  
    ],
    labels=['astype', "!= ''", "replace + notna", "replace + dropna", ],
    n_range=[2**k for k in range(1, 15)],
    xlabel='N',
    logx=True,
    logy=True,
    equality_check=pd.DataFrame.equals)

34

value_counts varsayılan olarak NaN'yi atlar, bu nedenle büyük olasılıkla "" ile uğraşıyorsunuzdur.

Böylece onları şu şekilde filtreleyebilirsiniz:

filter = df["Tenant"] != ""
dfNew = df[filter]

1
@Bobs çözümü benim için işe yaramadı. df.dropna (alt küme = ['kiracı'], inplace = Doğru) çalışır.
Amrita Sawant

1
Bunun için üzgünüm. "" Lerle uğraştığını sanıyordum. Çözümünüzü bir cevap olarak göndermelisiniz
Bob Haffner

9

Hücrenin beyaz boşluğa sahip olduğu bir durum var, göremiyorsunuz, kullan

df['col'].replace('  ', np.nan, inplace=True)

beyaz boşluğu NaN olarak değiştirmek için

df= df.dropna(subset=['col'])

5

Bu varyasyonu kullanabilirsiniz:

import pandas as pd
vals = {
    'name' : ['n1', 'n2', 'n3', 'n4', 'n5', 'n6', 'n7'],
    'gender' : ['m', 'f', 'f', 'f',  'f', 'c', 'c'],
    'age' : [39, 12, 27, 13, 36, 29, 10],
    'education' : ['ma', None, 'school', None, 'ba', None, None]
}
df_vals = pd.DataFrame(vals) #converting dict to dataframe

Bu çıktı (** - yalnızca istenen satırları vurgulayarak):

   age education gender name
0   39        ma      m   n1 **
1   12      None      f   n2    
2   27    school      f   n3 **
3   13      None      f   n4
4   36        ba      f   n5 **
5   29      None      c   n6
6   10      None      c   n7

Bu nedenle, 'eğitim' değeri olmayan her şeyi bırakmak için aşağıdaki kodu kullanın:

df_vals = df_vals[~df_vals['education'].isnull()] 

('~' DEĞİL anlamına gelir)

Sonuç:

   age education gender name
0   39        ma      m   n1
2   27    school      f   n3
4   36        ba      f   n5

0

Eksik dosyaların bulunduğu sütunları umursamıyorsanız, veri çerçevesinin ada sahip olduğunu Newve yeni veri çerçevesini aynı değişkene atamak istediğini göz önünde bulundurarak,

New = New.drop_duplicates()

Sütundaki boş değerler için özellikle satırları kaldırmak istiyorsanız, Tenantbu işi yapacaktır.

New = New[New.Tenant != '']

Bu, belirli bir değere sahip satırları kaldırmak için de kullanılabilir - yalnızca dizeyi istediği değere değiştirin.

Not : Boş bir dizge yerine bir tane varsa NaN, o zaman

New = New.dropna(subset=['Tenant'])
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.