使用 melt 和 unstack 在 pandas 中旋转数据

Pivot data in pandas using melt and unstack

给定以下数据:

data = pd.DataFrame(
    {
        "A": ["a", "a", "b", "b"],
        "B": ["x", "y", "p", "q"],
        "C": ["one", "two", "one", "two"],
    }
)

看起来像:

   A  B    C
0  a  x  one
1  a  y  two
2  b  p  one
3  b  q  two

我想创建以下内容:

data_out = pd.DataFrame(
    {
        "A": ["a", "b"],
        "one": ["x", "p"],
        "two": ["y", "q"],
    }
)

看起来像:

   A one two
0  a   x   y
1  b   p   q

我知道我可以按照以下方式做一些事情:

d_piv = pd.pivot_table(
    data,
    index=["A"],
    columns=["C"],
    values=["B"],
    aggfunc=lambda x: x,
).reset_index()

给出:

   A   B    
C    one two
0  a   x   y
1  b   p   q

可以从中清理列,但我想知道如何使用 melt 和 unstack 来解决这个问题?

我试过:

print(data.set_index("C", append=True).unstack())

给出:

     A         B     
C  one  two  one  two
0    a  NaN    x  NaN
1  NaN    a  NaN    y
2    b  NaN    p  NaN
3  NaN    b  NaN    q

这里不需要 NaN 值,所以我可以改为尝试:

data.index = [0, 0, 1, 1]
data.set_index(["A", "C"], append=True).unstack(-1).reset_index(level=-1)

给出:

   A   B    
C    one two
0  a   x   y
1  b   p   q

所以更接近了 - 但仍然感觉好像那里还有一些不必要的部分。

特别是像那样编码索引。

编辑

解决方案:

df.set_index('A').pivot(columns='C', values='B').reset_index().rename_axis(None, axis=1)

很好,但我想知道这里是否可以用unstack代替pivot?

首先,将A列设置为索引,然后使用df.pivot。为了获得准确的输出,我们必须重置索引并重命名轴。

(df.set_index("A").pivot(columns="C", values="B")
                  .reset_index()
                  .rename_axis(None, axis=1))


   A one two
0  a   x   y
1  b   p   q

使用df.unstack

df.set_index(["A", "C"])["B"].unstack().reset_index().rename_axis(None, axis=1)

   A one two
0  a   x   y
1  b   p   q