将 Pandas 数据框从宽格式转换为长格式

6

我不确定这些数据是否已经正确地被呈现为广义格式(wide format),但我的目的是实现以下内容:

将数据从d1的形状转换成d2的形状。

In [26]: d1 = pd.DataFrame({'where':['x','y'],
    ...: 'p1':[3,7],
    ...: 'p2':[11,12]})

In [27]: d2=pd.DataFrame({
    ...: 'where':['x','x','y','y'],
    ...: 'who':['p1','p2','p1','p2'],
    ...: 'value':[3,11,7,12]})

这看起来是:

In [10]: d1
Out[10]:
  where  p1  p2
0     x   3  11
1     y   7  12

In [11]: d2
Out[11]:
  where who  value
0     x  p1      3
1     x  p2     11
2     y  p1      7
3     y  p2     12

我认为这是 d1.pivot( ... ) 的某种形式,但我似乎无法弄清楚如何去处理。

因此,明确一下,我想使用 pandas 将数据 d1 重新塑造成 d2 的结构。

编辑

以下方法可行,但是方法比较差。

d3 = d1.pivot(columns='where').T.reset_index()
d3.columns = ['who','where','a','b']
d3 = d3.loc[:,['where','who','a','b']]
d3 = d3.sort_values('where')
d3.fillna(value=0,inplace=True)
d3['c'] = d3.a + d3.b
d3.drop(['a','b'],axis=1,inplace=True)
d3.columns=['where','who','value']

In [43]: d3
Out[43]:
  where who  value
0     x  p1    3.0
2     x  p2   11.0
1     y  p1    7.0
3     y  p2   12.0

编辑2

以下内容可行

In [49]: d1.melt(id_vars='where')
Out[49]:
  where variable  value
0     x       p1      3
1     y       p1      7
2     x       p2     11
3     y       p2     12

我想知道使用透视表是否可以实现这个操作?我原本以为所有这些操作都可以使用透视表函数来完成。

编辑3 - 获取原始结构的示例

上面我提到的是使用 pivot 函数,而不是使用 pivot_table 函数,不过以下示例是根据最终结果找回原始结构的一种方法。

d1.melt(id_vars='where').pivot_table(values="value", index="where", columns="variable")

variable    p1  p2
where       
x           3   11
y           7   12

透视表----融合或堆叠 - BENY
正如@YOBEN_S所指出的,我知道这个函数,我正在寻求如何使用它的指导。 - baxx
@YOBEN_S 我已经编辑了原帖 - baxx
2个回答

2

不,无法使用数据透视表来完成。你没有在数据框内部对值进行透视。

你可以使用透视功能将d2转换为d1。例如下面展示了如何将d1转换为d2(最初的请求),然后我们可以使用透视表将d2转换回d1。

d1.melt(id_vars='where')

  where variable  value
0     x       p1      3
1     y       p1      7
2     x       p2     11
3     y       p2     12


d1.melt(id_vars='where').pivot(values="value", index="where", columns="variable")

variable    p1  p2
where       
x           3   11
y           7   12

你正在尝试做的是将宽数据集转换为长数据集,这被称为“unpivot”。
使用顶级函数melt()及其对应的DataFrame.melt()可以将DataFrame转换为一种格式,在该格式中,一个或多个列是标识符变量,而所有其他列(称为测量变量)都被“unpivoted”到行轴上,只留下两个非标识符列:“variable”和“value”。这些列的名称可以通过提供var_name和value_name参数进行自定义。详见此链接

无法使用数据透视表完成此操作” - pandas中的pivotpivot_table是完全不同的东西,对吗?我没有提到使用数据透视表。 - baxx
不错的示例,展示了如何获取结构。 - baxx
pivot和pivot_table是相同的,唯一的区别在于pivot_table还具有聚合函数(更适用于数值数据)-虽然pivot()提供了各种数据类型(字符串,数字等)的通用旋转,但pandas还提供了pivot_table()以聚合数值数据进行旋转。 - sdhaus
所以我有点困惑,它们是相同的吗?在功能方面,哪一个是另一个的子集? - baxx
它们是相同的,pivot_table 是 pivot 的进化版本,包含了额外的功能。 - sdhaus

1
这应该能解决问题:
d1.set_index('where').unstack().reset_index().rename(columns={"level_0": "who", 0: "value"})

输出:

  who where  value
0  p1     x      3
1  p1     y      7
2  p2     x     11
3  p2     y     12

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