首页 > 解决方案 > 如何将 dict 转换为 pandas 多索引数据框

问题描述

我正在处理不同属性(例如 A、B、...)的元素(例如 a1、a2、...)之间的距离,我选择 adict来存储距离。具有以下dict形式:

mydict = {('A', ('a1','a2')): 1.0,
          ('A', ('a1','a3')): 0.5,
          ('A', ('a2','a1')): 1.1,
          ('A', ('a2','a3')): 0.8,
          ('A', ('a3','a1')): 1.2,
          ('A', ('a3','a2')): 1.2,
          ('B', ('b1','b2')): 1.0,
          ('B', ('b1','b3')): 0.5,
          ('B', ('b2','b1')): 1.1,
          ('B', ('b2','b3')): 0.8,
          ('B', ('b3','b1')): 1.2,
          ('B', ('b3','b2')): 1.2,
          }

因此,键dicttuples,第一个元素给出属性,第二个元素tuple本身给出两个元素,其距离在相应的值中给出。

现在我想以交叉表的形式显示数据,看起来应该像这样:

A   a1   a2   a3
a1    0  1.0   0.5
a2  1.1    0   0.8
a3  1.2  1.2    0

B   b1   b2   b3
b1    0  1.0   0.5
b2  1.1    0   0.8
b3  1.2  1.2    0

等等每个属性。

我试图将数据转换DataFrame为可能使用casstab熊猫的功能。我试图将 dict 的键转换为列表并使用pandas.MultiIndex.from_tuplesMultiIndex.to_frame但我没有得到可用的格式。

有什么建议如何处理这个问题或以不同的方式存储距离数据吗?

标签: pythonpandascrosstab

解决方案


我认为数据的格式很好。您只需要正确解包即可获得可用的数据框。

  • 从 dict 值和 dict 键构造数据框。
  • 将具有元素名称的索引级别解压缩到两列。
  • 使用适当的索引和列应用交叉表(应用于.fillna(0)结果以获得与您的问题完全相同的结构)。
df = pd.DataFrame(my_dict.values(), pd.MultiIndex.from_tuples(my_dict.keys()))
df[['first_element', 'second_element']] = df.index.get_level_values(1).to_list()
pd.crosstab(
            [df.index.get_level_values(0), df.first_element],
            df.second_element,
            values=df[0],
            aggfunc='sum'
            )

推荐阅读