Pandas DataFrame apply() ValueError:要解包的值太多(预期为 2)

Posted

技术标签:

【中文标题】Pandas DataFrame apply() ValueError:要解包的值太多(预期为 2)【英文标题】:Pandas DataFrame apply() ValueError: too many values to unpack (expected 2) 【发布时间】:2016-05-24 05:30:45 【问题描述】:

我刚开始接触 Python,虽然我很兴奋,但似乎我离 Python 思维还很远。

这是一个方法的例子,它到处都是“次优”这个词。 虽然这对于我相对较小的数据集来说已经足够了,但我想知道如何才能更好地编写它?

import pandas as pd
from pandas import DataFrame

# create sample log data frame
lg = pd.DataFrame(['Access violation at address 00A97...',
                   'Try to edit the splines or change...',
                   'Access violation at address 00F2B...',
                   'Please make sure the main electro...'], columns=['lg_msg'])

# define message classification
err_messages = [['Access violation', 'ACC-VIOL', 'PROG'],
                ['Please make sure th', 'ELE-NOT-PLACED', 'MOD'],
                ['Try to edit the splines', 'TRY-EDIT-SPLINES', 'MOD']]                

# lookup code
def message_code(msg_text):
    for msg in err_messages:
        if msg_text.startswith(msg[0]):
            return msg[1]
    return ''

# lookup type
def message_type(msg_text):
    for msg in err_messages:
        if msg_text.startswith(msg[0]):
            return msg[2]
    return ''               

lg['msg_code'] = lg['lg_msg'].apply(lambda x:  message_code(x))
lg['msg_type'] = lg['lg_msg'].apply(lambda x:  message_type(x))

我尝试创建一个函数来计算日志条目代码并立即键入:

def message_code_type(msg_text):
    for msg in err_messages:
        if msg_text.startswith(msg[0]):
            return (msg[1], msg[2])
    return ('', '')

lg['msg_code'], lg['msg_type'] = lg['lg_msg'].apply(lambda x:  message_code_type(x))

但得到:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-18-72f97d857539> in <module>()
----> 1 lg['msg_code'], lg['msg_code'] = lg['lg_msg'].apply(lambda x:  message_code_type(x))

ValueError: too many values to unpack (expected 2)

有没有办法不遍历数据框两次?

我们将不胜感激。

import sys
print(sys.version)
3.5.1 |Anaconda 2.4.0 (64-bit)| (default, Jan 29 2016, 15:01:46) [MSC v.1900 64 bit (AMD64)]

pd.__version__
'0.17.1'

【问题讨论】:

【参考方案1】:

使用 itertools 模块中的izip 试试这个:

from itertools import izip
lg['msg_code'], lg['msg_code'] = izip(*lg['lg_msg'].apply(lambda x:  message_code_type(x)))

In [21]:    lg
Out[21]:
    lg_msg  msg_code
0   Access violation at address 00A97...    PROG
1   Try to edit the splines or change...    MOD
2   Access violation at address 00F2B...    PROG
3   Please make sure the main electro...    MOD

抱歉,这是2.7,你应该可以使用内置的zip

lg['msg_code'], lg['msg_type'] = zip(*lg['lg_msg'].apply(lambda x:  message_code_type(x)))

    lg_msg  msg_code    msg_type
0   Access violation at address 00A97...    ACC-VIOL    PROG
1   Try to edit the splines or change...    TRY-EDIT-SPLINES    MOD
2   Access violation at address 00F2B...    ACC-VIOL    PROG
3   Please make sure the main electro...    ELE-NOT-PLACED  MOD

【讨论】:

谢谢,会试试的!一件事......我的错误,两个目标列具有相同的名称,这导致单个 msg_code 列。已经编辑了我的问题。 很遗憾,我的环境好像没有itertools [Anaconda3] C:\Users\[snip]&gt;pip install itertools Collecting itertools Could not find a version that satisfies the requirement itertools (from versions: ) No matching distribution found for itertools 你不必导入 itertools 在 python3 中使用zip,它是内置的。查看我发布的第二个链接中的示例。这个,特别是:x2, y2 = zip(*zip(x, y))。这是使用zipmap 的another SO question。

以上是关于Pandas DataFrame apply() ValueError:要解包的值太多(预期为 2)的主要内容,如果未能解决你的问题,请参考以下文章

pandas DataFrame apply()函数

pandas 的DataFrame.apply()

pandas DataFrame apply()函数

Python pandas.DataFrame.apply函数方法的使用

pandas编写自定义函数使用apply函数应用自定义函数基于Series数据生成新的dataframe

让 Pandas DataFrame apply() 使用所有内核?