2017-07-24 55 views
3

我有一個只包含空字符串和空字符串的pandas系列。我想將它們轉換爲'null'值(例如None)。將空(ish)字符串轉換爲空的最有效方法

def empty_str_to_null(s): 
    """Convert empty strings to None (null)""" 
    s.loc[s.str.strip().str.len() == 0] = None 
    return s 

foo = pd.Series(np.repeat([1,2,3,'',None,np.NaN, ' ', ' a'],1E6)) 

>>> %time bar = empty_str_to_null(foo) 

這個工程,但並不那麼快。

CPU times: user 7.67 s, sys: 260 ms, total: 7.93 s 
Wall time: 8.38 s 

我需要爲許多不同的領域重複這樣做。

有沒有更好的(更快)的方法?

+2

嘗試's.replace('',np.nan)',我不確定它是否是矢量的,但我確定它更快。 –

+0

這將工作與空(ISH)字符串......即,這只是空白的地方? – drstevok

回答

0

這裏有一個方法 -

def empty_str_to_null_slicer(s): 
    a = s.values.astype(str) 
    # slicer_vectorized from https://stackoverflow.com/a/39045337/ 
    mask = (slicer_vectorized(a,0,1)==' ') | (a=='') 
    s[mask] = None 
    return s 

採樣運行 -

In [245]: s = pd.Series(np.repeat([1,'',' ',None,np.NaN],2)) 

In [246]: s 
Out[246]: 
0  1 
1  1 
2   
3   
4   
5   
6 None 
7 None 
8  NaN 
9  NaN 
dtype: object 

In [247]: a = s.values.astype(str) 
    ...: mask = (slicer_vectorized(a,0,1)==' ') | (a=='') 
    ...: s[mask] = None 
    ...: 

In [248]: s 
Out[248]: 
0  1 
1  1 
2 None 
3 None 
4 None 
5 None 
6 None 
7 None 
8  NaN 
9  NaN 
dtype: object 

運行測試 -

途徑 -

# Original approach 
def empty_str_to_null(s0): 
    s = s0.copy() 
    """Convert empty strings to None (null)""" 
    s.loc[s.str.strip().str.len() == 0] = None 
    return s 

# Proposed approach 
def empty_str_to_null_slicer(s0): 
    s = s0.copy() 
    a = s.values.astype(str) 
    # slicer_vectorized from https://stackoverflow.com/a/39045337/3293881 
    mask = (slicer_vectorized(a,0,1)==' ') | (a=='') 
    s[mask] = None 
    return s 

計時 -

In [228]: foo = pd.Series(np.repeat([1,'',' ',None,np.NaN],1E6)) 

In [229]: %timeit empty_str_to_null(foo) 
1 loop, best of 3: 4.17 s per loop 

In [230]: %timeit empty_str_to_null_slicer(foo) 
1 loop, best of 3: 573 ms per loop 
+0

'slicer_vectorized(a,0,1)=='''只檢查字符串開頭的單個空白區域,還是檢查任意數量的空格?我試着讀你的其他答案,我可能會誤解。 – drstevok

+0

@drstevok'a'是字符串數組。所以,'slicer_vectorized(a,0,1)'是該數組中每個字符串的第一個字符。 'slicer_vectorized(a,0,2)'將是前兩個字符,依此類推。用'slicer_vectorized(a,0,1)==''',我們檢查第一個字符是否是空格。 – Divakar

+0

謝謝。從運行線剖析器,它看起來像我的功能的問題是'strip'步驟。我不能讓你的函數工作,如果我'slicer_vectorized(a,0,:)'...正在考慮檢查整個字符串是空白嗎? – drstevok

相關問題