【问题标题】:Pandas re-ordering values in Multi-Index columns on a row-by-row basisPandas 对多索引列中的值逐行重新排序
【发布时间】:2021-06-09 08:55:51
【问题描述】:

我有以下多索引表:

A B C D
t_1 t_2 t_1 t_2 t_1 t_2 t_1 t_2
x y x y x y x y x y x y x y x y
2.2 5.1 3.4 1.8 1.5 6.7 8.1 7.5 6.1 2.1 9.3 7.1 8.2 1.1 1.4 2.5
7.9 3.2 1.1 5.3 9.3 3.1 0.9 3.2 4.1 5.1 7.7 4.3 8.1 0.4 2.4 4.1

数据点 (x, y) 已随机分配到 A - D 列。我想通过 x 的值对它们重新排序 t_1 - 显示在 斜体。其他值对于重新排序无关紧要,但通过x-值t_1 携带到它们的新列。这意味着每一行都会以不同的方式重新排序

我想要一些处理上表的代码:

A B C D
t_1 t_2 t_1 t_2 t_1 t_2 t_1 t_2
x y x y x y x y x y x y x y x y
1.5 6.7 8.1 7.5 2.2 5.1 3.4 1.8 6.1 2.1 9.3 7.1 8.2 1.1 1.4 2.5
4.1 5.1 7.7 4.3 7.9 3.2 1.1 5.3 8.1 0.4 2.4 4.1 9.3 3.1 0.9 3.2

【问题讨论】:

  • 我没有得到这个问题。请给出更多解释。你是怎么得到那个结果表的。
  • 似乎所有 x (t_1) 都按升序排列。和 y (t_1) 按 desc 顺序排列。
  • @Pygirl 我添加了更多解释。只有 x(t_1) 用于排序,y(t_1)、x(t_2) 和 y(t_2) 值不相关,只是被 x(t_1) 排序“携带”。

标签: python pandas dataframe


【解决方案1】:

这是一个选项,主要涉及干预数据的形状、排序,然后使用重新调整的值和原始 df 列(一个 MultiIndex)来创建最终数据框:

df2 = df.T.unstack(level=0).T.reset_index(level=0, col_fill='row')
df2 = df2.sort_values([('level_0', 'row'), ('t_1', 'x')], ignore_index=True)
values = df2.drop(('level_0', 'row'), axis=1).values.reshape(2, -1)
df3 = pd.DataFrame(data=values, columns=df.columns)  # using original df's columns

输出:

                    A                   B                   C                   D
        t_1       t_2       t_1       t_2       t_1       t_2       t_1       t_2
     x    y    x    y    x    y    x    y    x    y    x    y    x    y    x    y
0  1.5  6.7  8.1  7.5  2.2  5.1  3.4  1.8  6.1  2.1  9.3  7.1  8.2  1.1  1.4  2.5
1  4.1  5.1  7.7  4.3  7.9  3.2  1.1  5.3  8.1  0.4  2.4  4.1  9.3  3.1  0.9  3.2

采用更易读但不准确的表格格式:

A B C D
t_1 t_2 t_1 t_2 t_1 t_2 t_1 t_2
x y x y x y x y x y x y x y x y
1.5 6.7 8.1 7.5 2.2 5.1 3.4 1.8 6.1 2.1 9.3 7.1 8.2 1.1 1.4 2.5
4.1 5.1 7.7 4.3 7.9 3.2 1.1 5.3 8.1 0.4 2.4 4.1 9.3 3.1 0.9 3.2

【讨论】:

  • 我很难找到按 A、B、C、D 块行元素对它们进行排序的正确语法。 +1。看起来不错
  • 我会建议你使用这个 awesome.tool 来显示表格:tablesgenerator.com/markdown_tables
  • @Pygirl 谢谢。我通常在需要时使用df.to_markdown,但这根本不能很好地处理 MultiIndex 列。您链接的工具越来越近,但仍需要手动调整标题、删除重复的标题标签等,这并不理想。这是 OP 表中的相同问题。嗯,如果它有助于可读性,我可能会添加它。
【解决方案2】:

试试unstackgroupby:(我现在能想到的唯一解决方案)

df1 = df.unstack().unstack()
for col in df1.columns:
    a = []
    for i,g in df1[col].groupby(level=0):
        a.append((i,g.iloc[0]))
    get_sortedli = sorted(a, key=lambda x: x[1])
    order_col = [f1 for f1,f2 in get_sortedli]
    val = (df.iloc[col].reindex(order_col, axis=1, level=0))
    df.iloc[col] = val

df:

我把这想象成一个 4 块排列(A、B、C、D)的问题。安排好后获取值并将其分配给真实的数据框。

df1:

【讨论】:

  • @Benjamin wrt 编辑添加val.index = df1[col].index - 如您所见,没有必要,结果是相同的。 val的索引已经是那个了。
猜你喜欢
  • 2019-03-26
  • 2018-10-28
  • 2019-02-08
  • 2019-02-02
  • 2019-02-05
  • 2020-01-04
  • 2019-08-16
  • 2020-12-28
  • 2020-07-22
相关资源
最近更新 更多