2016-05-31 106 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