有没有办法让元组作为 Pandas 中的索引正常工作?

问题描述 投票:0回答:1

我想在 Pandas 中使用 MultiIndex,在每个级别我都有一个嵌套元组。我知道原则上我可以打开这个东西的包装,但这会不太清晰和烦人。一般来说,元组的元素(类名和一些参数)只有在一起才有意义,我想让它更难以无意义的对结束,元组有不同的长度,并且我想使用 MultiIndex。来自_产品。

创建 DataFrame 和访问值时一切正常,但在编写时我得到了意想不到的结果。

在一个简单的例子中,代码如下:

import pandas as pd
index=pd.MultiIndex.from_arrays([[("foo","spam"),("foo","spam")],[("bar","egg"),("bar","egg")],[("baz","bacon"),("pam","bacon")]])
this_index = (("foo","spam"),("bar","egg"),("baz","bacon"))
df = pd.DataFrame(index=index, columns=["value"])
print(df)
print(df.loc[this_index])
df.loc[this_index]=0
# df.loc[this_index,"value"]=0
print(df)

首先打印我期望的表(三个元组作为索引,列值中为 NaN),然后打印正确检索到的值 NaN,但在最后一行显示两个名为“bar”和“egg”的额外列,均设置为 0:

                                    value  bar  egg
(foo, spam) (bar, egg) (baz, bacon)     0  0.0  0.0
                       (pam, bacon)   NaN  NaN  NaN

在这种情况下,使用注释行进行赋值可以得到预期的结果。

但是,就我而言,我也需要“垃圾邮件”、“鸡蛋”和“培根”作为元组。 如果我更改上面代码中的第 2 行和第 3 行:

index=pd.MultiIndex.from_arrays([[("foo",("spam",)),("foo",("spam",))],[("bar",("egg",)),("bar",("egg",))],[("baz",("bacon",)),("pam",("bacon",))]])
this_index = (("foo",("spam",)),("bar",("egg",)),("baz",("bacon",)))

我再次获得了前两个打印的预期行为,第三个打印给出了(现在以某种方式预期):

                                             value  bar  (egg,)
(foo, (spam,)) (bar, (egg,)) (baz, (bacon,))     0  0.0     0.0
                             (pam, (bacon,))   NaN  NaN     NaN

但是尝试与上面相同的解决方法会给出:

ValueError: setting an array element with a sequence. The requested array has an inhomogeneous shape after 2 dimensions. The detected shape was (3, 2) + inhomogeneous part.

而且我找不到任何方法来适应这个技巧。

我目前发现的最好的解决方法是在元组上使用 str() ,然后在需要时再次解析内容,但我觉得应该有更好的方法。我在这里发现的唯一痕迹是对这个答案的未答复评论。

python pandas tuples
1个回答
0
投票

如果我理解正确,你的问题是这个作业:

index=pd.MultiIndex.from_arrays([[("foo",("spam",)),("foo",("spam",))],[("bar",("egg",)),("bar",("egg",))],[("baz",("bacon",)),("pam",("bacon",))]])
this_index = (("foo",("spam",)),("bar",("egg",)),("baz",("bacon",)))

df = pd.DataFrame(index=index, columns=["value"])
df.loc[this_index, 'value']=0

您可以使用列或索引的列表来解决这个问题:

df.loc[this_index, ['value']] = 0

# or
df.loc[[this_index], 'value'] = 0

输出:

                                             value
(foo, (spam,)) (bar, (egg,)) (baz, (bacon,))     0
                             (pam, (bacon,))   NaN
© www.soinside.com 2019 - 2024. All rights reserved.