2016-03-23 34 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