2016-03-23 63 views
2

我已經讓這個腳本在過去的2到3個月內運行得很好,然後由於什麼原因我不知道它只是決定它會打破我。我沒有更新Python或任何我在這個腳本中使用的庫,但無論如何,現在我需要幫助解決它。ValueError:需要多個值才能解包,我怎樣才能讓我的代碼更健壯?

要開始數據幀是如下

Company, Registered date, Contact name, Contact email, Contact phone 

我通過所有與「_」

下一步是分裂「CONTACT_NAME」轉換爲小寫和更換空間清理那些列列開始爲「(第一)(最後)」,即「John Doe」,我想爲第一個和最後一個添加2列。新DF如下,

company, registered_date, contact_name, first_name, last_name, contact_email, contact_phone 

該程序正在拆分聯繫人名稱和/或創建新列。我一直在使用要做到這一點代碼行是:

df1['first_name'], df1['last_name'] = zip(*df1['registrant_name'].apply(lambda x: x.split(' ', 1))) 

回溯說:

File "(name).py", line 123 
df1['first_name'], df1['last_name'] = zip(*df1['registrant_name'].apply(lambda x: x.split(' ', 1))) 
ValueError: need more than 1 value to unpack 

當我通過一些東西,我發現有人用同樣的問題在使用line.split看了(不在Pandas裏面,只是一般的Python),有人說這可能是因爲這兩個值都不存在。果然,這似乎是3個月來的第一次,我只是在「contact_name」列中只有一個值,而不是「John Doe」,而只是「John」(幸運的是,這實際上是第一個入口在這個CSV中,否則我會被困住一段時間試圖查看每一行)。

所以我的問題是,如何讓我的代碼更健壯,如果再次出現這個問題,我們可以解決它。我在想,我想要做的是如果沒有空間,它會將當前值作爲「first_name」,然後添加「NaN」作爲姓。因爲循環並不理想,所以我只是不知道如何在DF中完成它。

感謝您的幫助!

+0

在你的代碼可能已經避免了lambda函數和使用'DF1 [「registrant_name」]海峽。 split()'代替。 – IanS

回答

2

也許使用itemgetterstr.partition

import pandas as pd 


df = pd.DataFrame(["foo bar" , "foo", "bar barf"],columns=["name"]) 
from operator import itemgetter 


df['first_name'], df['last_name'] = zip(*df['name'].apply(lambda x: itemgetter(0,2)(x.partition(' ')))) 

這會給你一個空字符串缺少姓氏,所以我不確定這是否合意。

 name first_name last_name 
0 foo bar  foo  bar 
1  foo  foo   
2 bar barf  bar  barf 

不知道這是否會更快或沒有,但它避免了在lambda:

import pandas as pd 

df = pd.DataFrame(["foo bar" , "foo", "bar barf"],columns=["name"]) 
from operator import itemgetter 


df['first_name'], df['last_name'] = zip(*map(itemgetter(0, 2), df['name'].str.partition(" ").values)) 
print(df) 
+1

不錯,我忘記了'分區'。 – IanS

+0

嗯。運算符是Python中的默認庫嗎?或者是我需要安裝的東西,因爲它會引發一堆試圖運行該代碼的錯誤。 – Mxracer888

+0

你會得到什麼錯誤? 'operator.itemgetter'是一個內置的方法 –

1

您在尋找的是從'John Doe'['John', '']'John'返回['John', 'Doe']的方法。這樣你總會有兩個值解包。

當然有不同的解決方案,但我可以建議一個避免了一個循環:

x.split(' ', 1) if ' ' in x else [x, ''] 

堵到你lambda功能這應該避免您遇到的錯誤。請注意,以第一條帶空格,因爲它們會使測試無效是非常重要的:

df1['registrant_name'].str.strip().apply(lambda x: x.split(' ', 1) if ' ' in x else [x, '']) 
+0

請注意,我花了很長時間避免剝離名稱兩次,如'x.split()if len(x.split())> 1 else [x,'']'。 – IanS