2016-04-06 9 views
1

Birçok veri türüne (Excel'den yüklenen) sahip bir Pandalar veri çerçevesi yüklüyorum. İki özel sütun şamandıralı olmalı, ancak bazen "ölçülmemiş" gibi rastgele bir yoruma girilen bir araştırmacı. İki sütundan birindeki herhangi bir değerin bir sayı olmadığı ve diğer sütunlarda sayısal olmayan verileri koruduğu satırları bırakmam gerekiyor.Bir Dataframe öğesinin iki sütunundan sayısal olmayan verileri filtreleyen Panda'ları kullanma

A B C    D 
0 1 96 12    apples 
1 2 33 Not measured oranges 
2 3 45 15    peaches 
3 4  66    plums 
4 5 8 42    pears 

Ben buna nasıl açık değilim: Bu (gerçek tablo birkaç bin satır var ...) gibi basit bir kullanım örneği

bu veri tablosunda sonuçlanır
import pandas as pd 

df = pd.DataFrame(dict(A = pd.Series([1,2,3,4,5]), B = pd.Series([96,33,45,'',8]), C = pd.Series([12,'Not measured',15,66,42]), D = pd.Series(['apples', 'oranges', 'peaches', 'plums', 'pears']))) 

görünüyor tablo:

A B C    D 
0 1 96 12    apples 
2 3 45 15    peaches 
4 5 8 42    pears 

Ben dropna çalıştı, ancak tipleri sayısal olmayan girişleri olmadığından "nesne" dir. Değerleri tüm tabloyu dönüştürmeden veya satırdaki diğer verilere olan ilişkisini kaybeden bir seriyi yapmadan floatlara dönüştüremiyorum. Belki anlamadığım basit bir şey var mı?

cevap

1

Önce all değerleri notnull olup olmadığını kontrol, sütunlar B, C ve applyto_numeric ile alt kümesini oluşturabilirsiniz. Sonra boolean indexing kullanın:

isnull ve xor ( ^) ile
print df[['B','C']].apply(pd.to_numeric, errors='coerce').notnull().all(axis=1) 
0  True 
1 False 
2  True 
3 False 
4  True 
dtype: bool 

print df[df[['B','C']].apply(pd.to_numeric, errors='coerce').notnull().all(axis=1)] 
    A B C  D 
0 1 96 12 apples 
2 3 45 15 peaches 
4 5 8 42 pears 

Sonraki çözüm kullanımı str.isdigit:

print df['B'].str.isdigit().isnull()^df['C'].str.isdigit().notnull() 
0  True 
1 False 
2  True 
3 False 
4  True 
dtype: bool 

print df[df['B'].str.isdigit().isnull()^df['C'].str.isdigit().notnull()] 
    A B C  D 
0 1 96 12 apples 
2 3 45 15 peaches 
4 5 8 42 pears 

Ama isnull ile to_numeric ile çözüm ve notnull en hızlı:

print df[pd.to_numeric(df['B'], errors='coerce').notnull() 
    ^pd.to_numeric(df['C'], errors='coerce').isnull()] 

    A B C  D 
0 1 96 12 apples 
2 3 45 15 peaches 
4 5 8 42 pears 

Zamanlamalarını:

#len(df) = 5k 
df = pd.concat([df]*1000).reset_index(drop=True) 

In [611]: %timeit df[pd.to_numeric(df['B'], errors='coerce').notnull()^pd.to_numeric(df['C'], errors='coerce').isnull()] 
1000 loops, best of 3: 1.88 ms per loop 

In [612]: %timeit df[df['B'].str.isdigit().isnull()^df['C'].str.isdigit().notnull()] 
100 loops, best of 3: 16.1 ms per loop 

In [613]: %timeit df[df[['B','C']].apply(pd.to_numeric, errors='coerce').notnull().all(axis=1)] 
The slowest run took 4.28 times longer than the fastest. This could mean that an intermediate result is being cached 
100 loops, best of 3: 3.49 ms per loop 
+0

Teşekkürler! Sürdürülebilirlik için değil, ilk çözüm olanı seviyorum. Çalışıyor gibi görünüyor! Bir gün vereceğim ve ortaya çıkan herhangi bir sorun olup olmadığını veya birisinin daha basit bir çözümle yanıt verip vermediğini göreceğim. – ZSG

İlgili konular