2016-05-31 104 views
2

我正在处理文本数据,我只想根据现有列填充新列。使用拆分来填充熊猫数据框中的列

示例:列sourceEncodedID可能具有类似于a.b.c的值,并且如果还有第二部分可用,我只想提取字符串的第二部分,即b。下面是一些示例值:

sourceEncodedID Branch  
a.b.c    b  
c.r.d    r  
a     a  
p     p 

要做到这一点,我想出了下面的代码:

for i in range(0,20350): 
    if len(str(artifacts.sourceEncodedID[i]).split('.')) > 1: 
     artifacts['branch'][i] = str(artifacts.sourceEncodedID[i]).split('.')[1] 
    else: 
     artifacts['branch'][i] = str(artifacts.sourceEncodedID[i]) 

只有20K的数据帧行,但这段代码需要几分钟到执行之前,永不完成和呈现我的浏览器无反应(我使用ipython notebook)。我原以为这会在几秒钟内运行。

在这段代码中显然有些东西我无法捕捉到吗?我如何解决它?

回答

1

UPDATE2: - 我相信这将是更快一点:

x['new'] = x.sourceEncodedID.str.replace(r'[^\.]*\.([^\.]*).*', r'\1') 

上20K时序DF:

In [155]: x.shape 
Out[155]: (20000, 2) 

In [156]: %timeit x['new'] = x.sourceEncodedID.str.replace(r'[^\.]*\.([^\.]*).*', r'\1') 
10 loops, best of 3: 127 ms per loop 

UPDATE:

In [68]: x['new'] = x.sourceEncodedID 

In [69]: x 
Out[69]: 
    sourceEncodedID Branch new 
0   a.b.c  b a.b.c 
1   c.r.d  r c.r.d 
2    a  a  a 
3    p  p  p 

In [70]: x.ix[x.sourceEncodedID.str.contains('\.'), 'new'] = x.sourceEncodedID.str.split('\.', expand=True)[1] 

In [71]: x 
Out[71]: 
    sourceEncodedID Branch new 
0   a.b.c  b b 
1   c.r.d  r r 
2    a  a a 
3    p  p p 

与工作时首先总是熊猫数据帧尝试找到矢量化的解决方案。只有在绝对不可能的情况下,仔细检查它,并且只有在尝试通过循环方法之后,它才会慢几个数量级。

OLD答案:

试试这个:

In [61]: x.sourceEncodedID.str.split('\.', expand=True)[1] 
Out[61]: 
0  b 
1  r 
2 None 
3 None 
Name: 1, dtype: object 
+0

感谢这么多,它做的工作。您能否指出我的代码中对我而言不明显的愚蠢行为? – Patthebug

+0

@Patthebug,我已经更新了我的答案 - 请检查 – MaxU

+0

感谢您添加解释,我很感激! 我想这只是一个有点令人沮丧的事情,一个人不得不知道熊猫的矢量化功能,并回到基础知识花费你的时间。我同意矢量化解决方案更整洁,但你必须知道它们。一次一个功能! – Patthebug