2016-04-06 281 views
1

我正在加載一個擁有多種數據類型(從Excel加載)的Pandas數據框。兩個特定的列應該是浮動的,但偶爾一位研究人員隨機發表評論,如「未測量」。我需要刪除其中兩列之一中的值不是數字的任何行,並在其他列中保留非數字數據。一個簡單的例子看起來是這樣的(真正的表有幾千行...)使用Pandas過濾來自Dataframe兩列的非數字數據

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

導致此數據表:

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 

我不太清楚怎麼到這表:

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

我試過dropna,但類型是「對象」,因爲有非數字條目。 我無法將值轉換爲浮點數,無需轉換整個表,或者一次執行一個與該行中的其他數據失去關係的系列。也許有一些簡單的我不理解?

回答

1

可以先創建一個列BCapplyto_numeric子集,檢查是否allnotnull。然後使用boolean indexing

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 

下一個解決方案使用str.isdigitisnull和XOR(^):

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 

但解決方案與to_numericisnullnotnull是最快的:

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 

計時

#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

謝謝!我喜歡第一個適用於可維護性的解決方案。它似乎工作!我會給它一天,看看是否有任何問題出現,或者如果有人用更簡單的解決方案做出迴應。 – ZSG

相關問題