Python ValueError:解包需要超过1个值,如何使代码更健壮?

Python ValueError:解包需要超过1个值,如何使代码更健壮?,python,python-2.7,pandas,Python,Python 2.7,Pandas,在过去的两三个月里,我的脚本运行得很好,但不知出于什么原因,我决定它会毁了我。我还没有更新Python或我在这个脚本中使用的任何库,但不管怎样,现在我需要帮助修复它 启动数据帧的步骤如下 Company, Registered date, Contact name, Contact email, Contact phone 我通过将所有列转换为小写并将空格替换为“\”来清理这些列 下一步是拆分“contact_name”列,该列以“(first)(last)”开头,即“John Doe”,我想

在过去的两三个月里,我的脚本运行得很好,但不知出于什么原因,我决定它会毁了我。我还没有更新Python或我在这个脚本中使用的任何库,但不管怎样,现在我需要帮助修复它

启动数据帧的步骤如下

Company, Registered date, Contact name, Contact email, Contact phone
我通过将所有列转换为小写并将空格替换为“\”来清理这些列

下一步是拆分“contact_name”列,该列以“(first)(last)”开头,即“John Doe”,我想为first和last添加两列。新的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个月来我第一次在“联系人姓名”列中只得到一个值,所以我不是“John Doe”,而是“John”(幸运的是,这是CSV中的第一个条目,否则我会被难倒一段时间,试图查看每一行)

所以我的问题是,我如何使我的代码更健壮,这样如果这个问题再次出现,我们就可以解决它。我想我要做的是,如果没有空格,它只会将当前值作为“first_name”,然后添加“NaN”作为姓氏。我只是不知道如何在DF中实现,因为循环并不理想


谢谢你的帮助

您正在寻找的是一种从
'John Doe'
返回
['John','Doe']
的方法,以及从
'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, ''])
可能将itemgetter与str.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)

请注意,为了避免两次剥离名称,我做了很多工作,例如在
x.split()中,如果len(x.split())>1 else[x',]
。在您的代码中,您可以避免使用lambda函数,而是使用
df1['registant\u name'].str.split()
。很好,我忘记了
分区
的问题。操作符是Python中的默认库吗?或者它是我需要安装的东西,因为它在运行代码时会抛出一堆错误。你会得到什么错误
operator.itemgetter
是一种内置方法哦,没关系,我知道问题出在哪里了。你在df中使用了'name',只需将其更改为'contact_name'的实际列名:)哈哈,够公平的了!对我来说,这是一个很好的练习,学习如何通读这些信息,并试着自己找出一些东西;)这似乎工作得很好!
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)