ValueError:在 Pandas 数据帧上使用 itertuples() 时解包的值太多

Posted

技术标签:

【中文标题】ValueError:在 Pandas 数据帧上使用 itertuples() 时解包的值太多【英文标题】:ValueError: too many values to unpack when using itertuples() on pandas dataframe 【发布时间】:2016-10-15 15:14:40 【问题描述】:

我正在尝试根据我在这里找到的答案将一个简单的 pandas 数据框转换为一个嵌套的 JSON 文件:pandas groupby to nested json

我的分组数据框如下所示:

                  firstname lastname  orgname         phone        mobile  email
teamname members                                                           
1        0            John      Doe     Anon  916-555-1234          none   john.doe@wildlife.net 
         1            Jane      Doe     Anon  916-555-4321  916-555-7890   jane.doe@wildlife.net
2        0          Mickey    Moose  Moosers  916-555-0000  916-555-1111   mickey.moose@wildlife.net
         1           Minny    Moose  Moosers  916-555-2222          none   minny.moose@wildlife.net  

我的代码是:

data = pandas.read_excel(inputExcel, sheetname = 'Sheet1', encoding = 'utf8')
grouped = data.groupby(['teamname', 'members']).first()

results = defaultdict(lambda: defaultdict(dict))

for index, value in grouped.itertuples():
    for i, key in enumerate(index):
        if i ==0:
            nested = results[key]
        elif i == len(index) -1:
            nested[key] = value
        else:
            nested = nested[key]

print json.dumps(results, indent = 4)

我在第一个“for”循环中收到以下错误。在这种情况下导致此错误的原因是什么?如何修复它以输出嵌套的 json?

    for index, value in grouped.itertuples():
ValueError: too many values to unpack

【问题讨论】:

【参考方案1】:

当使用itertuples() 时,索引作为元组的一部分包含在内,因此for index, value in grouped.itertuples(): 没有任何意义。事实上,itertuples() 使用的是 namedtuple,而 Index 是其中一个名称。

考虑以下设置:

data = 'A': list('aabbc'), 'B': [0, 1, 0, 1, 0], 'C': list('vwxyz'), 'D': range(5,10)
df = pd.DataFrame(data).set_index(['A', 'B'])

产生以下 DataFrame:

     C  D
A B      
a 0  v  5
  1  w  6
b 0  x  7
  1  y  8
c 0  z  9

然后在df.itertuples() 中打印每个元组:

Pandas(Index=('a', 0), C='v', D=5)
Pandas(Index=('a', 1), C='w', D=6)
Pandas(Index=('b', 0), C='x', D=7)
Pandas(Index=('b', 1), C='y', D=8)
Pandas(Index=('c', 0), C='z', D=9)

所以,您可能想要做的是类似于下面的代码,将value 替换为t[1:]

for t in grouped.itertuples():
    for i, key in enumerate(t.Index):
        ...

如果您想访问namedtuple 的组件,您可以按位置或按名称访问。因此,对于您的 DataFrame,t[1]t.firstname 应该是等价的。请记住 t[0] 是索引,因此您的第一列从 1 开始。

【讨论】:

如果我运行这两行,我得到:for i, key in enumerate(t.index): TypeError: 'builtin_function_or_method' object is not iterable 索引应大写:enumerate(t.Index). 这给了我一个不同的错误:for i, key in enumerate(t.Index): AttributeError: 'tuple' object has no attribute 'Index' 您使用的是哪个版本的pandas(请参阅pd.__version__)?如果它是旧版本,itertuples 可能尚未实现为namedtuple,因此尝试按名称访问它可能不起作用。尝试按位置调用它:enumerate(t[0])。如果这不起作用,请尝试查看itertuples 生成的一些元组,看看它实际为您生成了什么,并相应地调整您的代码。 这是我的最终代码data = pandas.read_excel(inputExcel, sheetname = 'SCAT Teams', encoding = 'utf8') grouped = data.groupby(['teamname', 'members']).first() print grouped results = defaultdict(lambda: defaultdict(dict)) for t in grouped.itertuples(): for i, key in enumerate(t.Index): if i ==0: nested = results[key] elif i == len(t.Index) -1: nested[key] = t else: nested = nested[key] jsonOutput = json.dumps(results, indent = 4)【参考方案2】:

据我了解 itertuples,它将返回一个元组,其中第一个值是索引,其余值是所有列。您只有index, value in grouped.itertuples(),这意味着它试图将所有列解压缩到一个变量中,这是行不通的。 groupby 可能也会发挥作用,但它仍应包含结果中的所有值,这意味着您仍然有太多列被解压。

【讨论】:

以上是关于ValueError:在 Pandas 数据帧上使用 itertuples() 时解包的值太多的主要内容,如果未能解决你的问题,请参考以下文章

在 pandas 数据帧上应用 Pyspark 管道

为啥 numpy 函数在 pandas 系列/数据帧上这么慢?

在具有多个参数的 pandas 数据帧上应用滚动函数

在数据帧上的 pandas groupby 之后循环遍历组

在 pandas 数据帧上同时操作 groupby 和 resample?

在 pandas 数据帧上并行调用函数