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() 时解包的值太多的主要内容,如果未能解决你的问题,请参考以下文章
为啥 numpy 函数在 pandas 系列/数据帧上这么慢?