2016-10-04 57 views
1

一個非常基本的qs傢伙 - thans vm用於查看。我想刪除Col1中包含任何字符串的行 - 僅關注Col1中的數值。熊貓刪除任何字符串的行

輸入:

 Col1 Col2 Col3 
0  123 48.0 ABC 
1  45 85.0 DEF 
2 A.789 66.0 PQR 
3 RN.35 9.0 PQR 
4  LMO 12.0 ABC 

輸出:

 Col1 Col2 Col3 
0 123.0 48.0 ABC 
1  45.0 85.0 DEF 

我試圖

test = input_[input_['Col1'].str.contains(r'ABCDEGGHIJKLMNOPQRSTUVWXYZ.')] 

但是看到這個錯誤

ValueError: cannot index with vector containing NA/NaN values

您可以:

  • 給出一個簡短的解釋,爲什麼這是行不通的?
  • 什麼是備用解決方案?

回答

4

這樣做:

import re 
regex = re.compile("[a-zA-Z]+") 
df.ix[df.col1.map(lambda x: regex.search(x) is None)] 
+0

所以我沒有這樣的: 'input_.ix [input_.Col1.map(拉姆達X:regex.search(x)是無)]' 並得到錯誤: 'TypeError:預期的字符串或緩衝區' – spiff

+1

因爲我不知道col1的類型,所以我認爲它是字符串並執行該過程。如果不是,它會引發這樣的例外。你可以這樣做: df.ix [df.col1.map(lambda x:regex.search(str(x))is None)] 將col1轉換爲字符串類型並再次運行。 – Howardyan

+0

熱潮!這是做到了 - 謝謝vm。我可以問你爲什麼我的方式不起作用嗎? – spiff

2

boolean indexing和條件與to_numeric其中參數errors='coerce'意味着如果數據不是數字轉換爲NaN另一種更快的解決方案 - 因此你需要找到所有notnullNaN數據:

print (pd.to_numeric(df.Col1, errors='coerce')) 
0 123.0 
1  45.0 
2  NaN 
3  NaN 
4  NaN 
Name: Col1, dtype: float64 

print (pd.to_numeric(df.Col1, errors='coerce').notnull()) 
0  True 
1  True 
2 False 
3 False 
4 False 
Name: Col1, dtype: bool 

df = df[pd.to_numeric(df.Col1, errors='coerce').notnull()] 
print (df) 
    Col1 Col2 Col3 
0 123 48.0 ABC 
1 45 85.0 DEF 

時序

#[100000 rows x 3 columns]  
df = pd.concat([df]*10000).reset_index(drop=True) 

In [16]: %timeit (df.ix[df.Col1.map(lambda x: re.compile("[a-zA-Z]+").search(x) is None)]) 
10 loops, best of 3: 57.7 ms per loop 

In [17]: %timeit (df[pd.to_numeric(df.Col1, errors='coerce').notnull()]) 
10 loops, best of 3: 22 ms per loop 

In [18]: %timeit (df[~df['Col1'].astype(str).str.contains(r'[ABCDEGGHIJKLMNOPQRSTUVWXYZ.]', na=False)]) 
10 loops, best of 3: 38.8 ms per loop 

您的解決方案:

我想你需要轉換爲strastype,然後添加[]used to indicate a set of characters和最後的附加參數na=False,因爲它似乎有些NaN值是col1,然後被轉換成False

print (df['Col1'].astype(str).str.contains(r'[ABCDEGGHIJKLMNOPQRSTUVWXYZ.]', na=False)) 
0 False 
1 False 
2  True 
3  True 
4  True 
Name: Col1, dtype: bool 

然後需要通過~反轉布爾掩碼,並使用boolean indexing

print (df[~df['Col1'].astype(str).str.contains(r'[ABCDEGGHIJKLMNOPQRSTUVWXYZ.]', na=False)]) 
    Col1 Col2 Col3 
0 123 48.0 ABC 
1 45 85.0 DEF 
+0

非常感謝你的詳細解答! – spiff

+0

我還添加了您的解決方案的時間安排,接受的解決方案的速度更快;) – jezrael