在 Pandas 中将两个 MultiIndex 级别合并为一个

Posted

技术标签:

【中文标题】在 Pandas 中将两个 MultiIndex 级别合并为一个【英文标题】:Merge two MultiIndex levels into one in Pandas 【发布时间】:2017-06-18 16:04:57 【问题描述】:

我有一个 MultiIndexed 的 Pandas 数据框。第二层包含年份 ([2014,2015]),第三层包含月份编号 ([1, 2, .., 12])。我想将这两个合并到一个级别,例如 - [1/2014, 2/2014 ..., 6/2015]。怎么可能做到这一点?

我是熊猫新手。搜索了很多,但找不到任何类似的问题/解决方案。

编辑:我找到了一种方法来避免与this question 的答案完全这样做。我应该以这种方式创建我的数据框。这似乎是按 DateTime 进行索引的方法。

【问题讨论】:

分享 df.columns 给我们 【参考方案1】:

考虑pd.MultiIndexpd.DataFramemuxdf

mux = pd.MultiIndex.from_product([list('ab'), [2014, 2015], range(1, 3)])

df = pd.DataFrame(dict(A=1), mux)

print(df)

          A
a 2014 1  1
       2  1
  2015 1  1
       2  1
b 2014 1  1
       2  1
  2015 1  1
       2  1

如果列表代表我们想要的索引,我们希望将列表重新分配给索引。

我希望第一级也一样

df.index.get_level_values(0)

我希望新的 2 级是当前 2 级和 3 级的字符串连接,但顺序相反

df.index.map('0[2]/0[1]'.format)

df.index = [df.index.get_level_values(0), df.index.map('0[2]/0[1]'.format)]

print(df)

          A
a 1/2014  1
  2/2014  1
  1/2015  1
  2/2015  1
b 1/2014  1
  2/2014  1
  1/2015  1
  2/2015  1

【讨论】:

不错的答案!你能详细说明'0[2]/0[1]'.format吗?具体来说,字符串中的这些数字是什么?它们与format 方法有什么关系?【参考方案2】:

您可以使用列表推导来重构您的索引。例如,如果您有一个 3 级索引,并且您想合并第二级和第三级:

lst = [(i, f'k/j') for i, j, k in df.index]
df.index = pd.MultiIndex.from_tuples(lst)

【讨论】:

【参考方案3】:

这只是对piRSquared答案的解释。

df.index.map('0[2]/0[1]'.format)

map() 方法有一个参数,它是在索引的每个元素上执行的回调。在这个例子中,方法恰好是python内置的str.format函数。

format 功能非常强大并且有很多功能(请参阅docs)。其中一个功能是通过指定位置参数来引用位置参数。这意味着

"Hello 1, I am 0, how are you?".format("Bob", "Alice")
--> Hello Alice, I am Bob, how are you?

这就是 piRSquared 答案中的零的来源。 通常情况下,如果只替换字符串中的一个参数,则不需要:

"Hello ".format("Bob")
--> Hello Bob

但是,在这种情况下,需要两个附加功能:

    在同一个字符串中多次使用一个元素,并且 从参数中选择一个子元素。

由于map 方法会将单个索引条目作为参数传递给格式函数,因此"0[2]" 指的是该索引的第三个元素。

现在原始问题中的索引具有三个级别,因此传递给format 函数的每个参数都是一个元组,其中包含对应于行索引的三个元素。

更详细但等效的解决方案是:

df.index.map(lambda idx: str(idx[2]) + '/' + str(idx[1]))

df.index.map(lambda idx: f'idx[2]/idx[1]')

【讨论】:

以上是关于在 Pandas 中将两个 MultiIndex 级别合并为一个的主要内容,如果未能解决你的问题,请参考以下文章

pandas:将两个 DataFrame 与已排序的 MultiIndex 连接起来,使得结果具有已排序的 MultiIndex

合并两个 pandas.core.indexes.multi.MultiIndex

两个 pandas MultiIndex 帧将每一行与每一行相乘

concat和sum multiindex pandas系列

使用 pandas 创建一个 multiIndex

部分级别上的 pandas MultiIndex 交集