2017-07-24 139 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

相关问题