python - 将 "grouped"列中的数据从长格式转换为宽/方形格式 pd.DataFrame

标签 python pandas dataframe pivot reshape

不太确定如何描述我正在寻找的内容,所以希望一个例子能有所帮助。

enter image description here

  • 每行最多包含 n 组观测值(此处,n=4)
  • 观察结果按 (id, x, y) 分组
  • id 代表某种唯一位置,x、y 是相关值

因此,例如,在第一行(索引 = 0)中,有两个观察值,分别位于 id=5(x=a,y=0)和 id=9(x=a,y=1)

我想 reshape /旋转数据,以便每个位置都有一个具有相应 x、y 值(可以为 NA)的列。

在这个例子中,看起来像这样

enter image description here

这里,再次查看第一行,(id=5, x=a, y=0) 已翻译 -> (x_5=a, y_5=0) 和 (id=9, x=a, y= 1) -> (x_9=a, y_9=1)。没有任何其他地点的观察结果。所以这些是<NA>

一直在尝试.pivot的所有组合我能想到但无法做到。

MRE 生成示例 DataFrame:

import pandas as pd

df_before = pd.DataFrame(
    [
        [5, 'a', '0', 9, 'a', '1'],
        [5, 'b', '3', 6, 'c', '3'],
        [9, 'c', '4'],
        [2, 'd', '12', 6, 'a', '3', 9, 'c', '2', 4, 'a', '3'],
        [6, 'a', '3'],
        [5, 'b', '0', 9, 'a', '4', 4, 'd', '9'],
        [2, 'c', '2', 9, 'g', '5', 4, 'g', '8']
    ],
    columns=['id_0','x_0','y_0', 'id_1', 'x_1', 'y_1', 'id_2', 'x_2', 'y_2', 'id_3', 'x_3', 'y_3']
).fillna(pd.NA)

df_after = pd.DataFrame(
    [
        [pd.NA, pd.NA, pd.NA, pd.NA, 'a', '0', pd.NA, pd.NA, 'a', '1'],
        [pd.NA, pd.NA, pd.NA, pd.NA, 'b', '3', 'c', '3', pd.NA, pd.NA],
        [pd.NA, pd.NA, pd.NA, pd.NA, pd.NA, pd.NA, pd.NA, pd.NA, 'c', '4'],
        ['d', '12', 'a', '3', pd.NA, pd.NA, 'a', '3', 'c', '2'],
        [pd.NA, pd.NA, pd.NA, pd.NA, pd.NA, pd.NA, 'a', '3', pd.NA, pd.NA],
        [pd.NA, pd.NA, 'd', '9', 'b', '0', pd.NA, pd.NA, 'a', '4'],
        ['c', '2', 'g', '8', pd.NA, pd.NA, pd.NA, pd.NA, 'g', '5']
    ],
    columns=['x_2', 'y_2', 'x_4', 'y_4', 'x_5', 'y_5', 'x_6', 'y_6', 'x_9', 'y_9']
)

最佳答案

您的操作本质上是melt/wide_to_long,然后向后旋转:

out = (pd.wide_to_long(df_before.reset_index(), 
                stubnames=['id_','x_','y_'],
                i='index', 
                j='old_id'
                )
       .groupby(['index','id_']).first().unstack('id_')
       .sort_index(level=[1,0], axis=1)
)
out.columns = [f'{x}{int(y)}' for x,y in out.columns]

输出:

       x_2  y_2  x_4  y_4  x_5  y_5  x_6  y_6  x_9  y_9
index                                                  
0      NaN  NaN  NaN  NaN    a    0  NaN  NaN    a    1
1      NaN  NaN  NaN  NaN    b    3    c    3  NaN  NaN
2      NaN  NaN  NaN  NaN  NaN  NaN  NaN  NaN    c    4
3        d   12    a    3  NaN  NaN    a    3    c    2
4      NaN  NaN  NaN  NaN  NaN  NaN    a    3  NaN  NaN
5      NaN  NaN    d    9    b    0  NaN  NaN    a    4
6        c    2    g    8  NaN  NaN  NaN  NaN    g    5

关于python - 将 "grouped"列中的数据从长格式转换为宽/方形格式 pd.DataFrame,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73572046/

相关文章:

python - 搜索日志,输出匹配前后的行

python - 如何根据其他两个系列及其索引创建 Pandas 系列?

Python: `validators.url`不接受1-9的端口号,但接受大于65535的端口?

python - 在 pandas 中切片 DataFrame?

r - 为什么 as.data.frame 忽略 col.names = vector

python - 属性错误: 'dict' object has no attribute 'is_active' (PyMongo And Flask)

python - 数据框按最大值排序并显示行名称

python - 如何替换数据框中的 Year 并在 Pandas 中将该值乘以 12

python - Groupby 算作一列,groupby 计算 Pandas 中另一列的唯一值数

python - 转换 pandas datetime 中的混合日期类型