Pandas - 透视表/堆叠/展开/融合

3

我有一个类似于这样的数据框:

姓名 值1 值2
A 100 101, 102, 103
B 200 201, 202, 203
C 300 301, 302, 303

我想要的结果是将所有与每个名称相对应的值2合并到一起。

姓名 数值1 数值2 数值3 数值4 数值5 数值6
A 100 101 100 102 100 103
B 200 201 200 202 200 203
C 300 301 300 302 300 303

这是我目前尝试过的代码:

dataframe.stack() dataframe.unstack() dataframe.melt(id_vars=['name'])

我需要转置数据,确保以下两点:

  1. 第一行保持不变,但与同一姓名关联的每个后续数值应该被转置到一个新列。
  2. 虽然第二个值 B (例如) 应该将其关联的值作为新值转置到 A 列的下面,但它不应该形成一个全新的列。
3个回答

5

请尝试:

def fn(x):
    vals = x.values.ravel()
    return pd.DataFrame(
        [vals],
        columns=[f"value {i}" for i in range(1, vals.shape[0] + 1)],
    )


out = (
    df.set_index("name")
    .groupby(level=0)
    .apply(fn)
    .reset_index()
    .drop(columns="level_1")
)
print(out.to_markdown())

输出结果:

名称 值1 值2 值3 值4 值5 值6
0 A 100 101 100 102 100 103
1 B 200 201 200 202 200 203
2 C 300 301 300 302 300 303

3

为每个名称展开值

(
    df.set_index('name')
    .groupby(level=0)
    .apply(lambda x: pd.Series(x.values.flat))
    .rename(columns=lambda x: f'value {x + 1}')
    .reset_index()
)

2

使用meltgroupbypivot_wider(来自pyjanitor)的一种选项:

# pip install pyjanitor
import pandas as pd
import janitor

(df
.melt('name', ignore_index = False)
.sort_index()
.drop(columns='variable')
.assign(header = lambda df: df.groupby('name').cumcount() + 1)
.pivot_wider('name', 'header', names_sep = ' ')
)
  name  value 1  value 2  value 3  value 4  value 5  value 6
0    A      100      101      100      102      100      103
1    B      200      201      200      202      200      203
2    C      300      301      300      302      300      303

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接