2017-10-29 59 views
12

227x4 DataFrame'im var, ülke isimleri ve rakamsal değerleri temizlemek için (wrangle?).Nasıl bir boolean maskesi kullanarak pandas DataFrame nan 'ile herhangi bir dizeleri' yerine nasıl?

İşte DataFrame bir soyutlama:

import pandas as pd 
import random 
import string 
import numpy as np 
pdn = pd.DataFrame(["".join([random.choice(string.ascii_letters) for i in range(3)]) for j in range (6)], columns =['Country Name']) 
measures = pd.DataFrame(np.random.random_integers(10,size=(6,2)), columns=['Measure1','Measure2']) 
df = pdn.merge(measures, how= 'inner', left_index=True, right_index =True) 

df.iloc[4,1] = 'str' 
df.iloc[1,2] = 'stuff' 
print(df) 

    Country Name Measure1 Measure2 
0   tua  6  3 
1   MDK  3 stuff 
2   RJU  7  2 
3   WyB  7  8 
4   Nnr  str  3 
5   rVN  7  4 

Nasıl ülke adı dokunmadan tüm sütunlarda np.nan ile dize değerleri yerine do?

Ben bir boolean maskesi kullanarak çalıştı

: ([1], [2], [3], [4], [5], [6], [7], [8]), ancak bir bulamadık Ben madenle ilgili birkaç soru baktım

mask = df.loc[:,measures.columns].applymap(lambda x: isinstance(x, (int, float))).values 
print(mask) 

[[ True True] 
[ True False] 
[ True True] 
[ True True] 
[False True] 
[ True True]] 

# I thought the following would replace by default false with np.nan in place, but it didn't 
df.loc[:,measures.columns].where(mask, inplace=True) 
print(df) 

    Country Name Measure1 Measure2 
0   tua  6  3 
1   MDK  3 stuff 
2   RJU  7  2 
3   WyB  7  8 
4   Nnr  str  3 
5   rVN  7  4 


# this give a good output, unfortunately it's missing the country names 
print(df.loc[:,measures.columns].where(mask)) 

    Measure1 Measure2 
0  6  3 
1  3  NaN 
2  7  2 
3  7  8 
4  NaN  3 
5  7  4 

Bu endişemi yanıtladı. ilgi

+0

"Bir meta-soru zorlamak i Burada bir soruyu formüle etmek için 3 saatten fazla sürüyor mu (araştırma dahil)? ” - Evet. [Yığın] ve tüm Yığın Değişim ağının başarısı, içeriğinin, hem soruların hem de cevapların yüksek kalitesine dayanmaktadır. Birkaç dakika içinde yüksek kaliteli bir soru arayamazsın. Şahsen, gerekli çabayı saatler arasında günlerin sıralarına koyardım. Kesinlikle bir gün veya daha fazlasını bir cevapla harcadım ve bekçinin en azından daha fazla çaba sarf etmesini bekliyorum. –

+0

Yan not: meta sorular [meta] 'da istenmelidir. –

+0

@ JörgWMittag Sadece kendimi denemekten vazgeçtikten sonra soruyu yazmak için harcanan zamanı sayıyordum. Bunu saymak zorunda olsaydım, gerçekten günler olurdu. Önümde birkaç saatim olduğunda metada bir soru yapacağım. Sorumu sormak için çok zaman ayırmakta aptalca hissediyordum. Ama şimdi daha iyi hissediyorum ve cevabın kalitesi, çabaya değdiğini kanıtlıyor. Teşekkür ederim! –

cevap

5

Ata okunur sütunlar:

cols = ['Measure1','Measure2'] 
mask = df[cols].applymap(lambda x: isinstance(x, (int, float))) 

df[cols] = df[cols].where(mask) 
print (df) 
    Country Name Measure1 Measure2 
0   uFv  7  8 
1   vCr  5  NaN 
2   qPp  2  6 
3   QIC  10  10 
4   Suy  NaN  8 
5   eFS  6  4 

Bir meta-soru, bunun (araştırma dahil) burada soru formüle etmek bana fazla 3 saat sürer normal mi?

Kanaatimce evet, iyi soru oluşturmak gerçekten zor.

+0

Senden hoşlanıyorum ama neden df2 = df.loc [:, measures.columns] .where (maske, inplace = True) 'yerine geçmiyor mu? Df.loc [:, measures.columns] .ama (maske) 'doğru yazdırır. hep inplace' dönmek 'Çünkü –

+0

' None', bu yüzden 'df2' Anlamıyorum .. Soruyu kaydetmiştiniz Yok – jezrael

+0

neden df.loc [:, measures.columns] .Where (maske, INPLACE = Doğru) df değiştirmez mi? –

7
cols = ['Measure1','Measure2'] 
df[cols] = df[cols].applymap(lambda x: x if not isinstance(x, str) else np.nan) 

veya

df[cols] = df[cols].applymap(lambda x: np.nan if isinstance(x, str) else x) 

Sonuç:

In [22]: df 
Out[22]: 
    Country Name Measure1 Measure2 
0   nBl  10.0  9.0 
1   Ayp  8.0  NaN 
2   diz  4.0  1.0 
3   aad  7.0  3.0 
4   JYI  NaN  10.0 
5   BJO  9.0  8.0 
+1

İyi bir çözüm değil mi? – Dark

+0

Ama niçin olumsuzluk x eğer isinstance değilse (x, str) 'yerine x isinstance (int, float) başka np.nan'? –

+1

Eğer negatif gerekiyorsa Nan ile tüm sayıların yerini o zaman x: np.nan isinstance (x, str) başka x' – Dark

5

Kullanım hataları ile sayısal bunun normal mi, yani

cols = ['Measure1','Measure2'] 
df[cols] = df[cols].apply(pd.to_numeric,errors='coerce') 
 
Country Name Measure1 Measure2 
0   PuB  7.0  6.0 
1   JHq  2.0  NaN 
2   opE  4.0  3.0 
3   pxl  3.0  6.0 
4   ouP  NaN  4.0 
5   qZR  4.0  6.0 
+2

Bence bu lambdadan kurtulabiliriz: 'df [cols] = df [cols] .apply (pd.to_numeric, errors = 'corece') ' – MaxU

+1

Teşekkürler bayım. Akşam yemeği yiyordum şimdi geldi. – Dark

+0

@Bharathshetty, cevabınız çok iyi (eğer mümkünse). Dizeyi gerçekten sayısal değerlere zorlayacağım ama bu sorunu formüle ettiğimde açık değildi. Odağım, boole maskesinin nasıl kullanılacağı ve neden yerinde çalışmadığıydı. –

İlgili konular