【问题标题】:Pivoting pandas DataFrame -- AssertionError: Index length did not match values旋转 pandas DataFrame - AssertionError:索引长度与值不匹配
【发布时间】:2013-09-10 20:11:29
【问题描述】:

我有一个 pandas.DataFrame,它不会以我期望的方式旋转。虽然pivot_table 正确安排了所有内容,但它使用聚合函数来实现这一点的事实令人反感。此外,pivot_table 似乎返回了一个不必要的复杂对象,而不是一个平面数据框。

考虑以下示例

import pandas as pd
df = pd.DataFrame({'firstname':['Jon']*3+['Amy']*2,
                   'lastname':['Cho']*3+['Frond']*2,
                   'vehicle':['bike', 'car', 'plane','bike','plane'],
                   'weight':[81.003]*3+[65.6886]*2,
                   'speed':[29.022, 95.1144, 302.952, 27.101, 344.2],})
df.set_index(['firstname','lastname','weight'])

print('------  Unnecessary pivot_table does averaging  ------')
print(pd.pivot_table(df, values='speed',
                         rows='firstname','lastname','weight'],
                         cols='vehicle'))

print('------ pivot method dies  ------')
print(df.pivot( index=['firstname','lastname','weight'],
                columns='vehicle',
                values='speed'))

pivot_table 结果是

vehicle                       bike      car    plane
firstname lastname weight                           
Amy       Frond    65.6886  27.101      NaN  344.200
Jon       Cho      81.0030  29.022  95.1144  302.952

有没有办法让pivot 提供与pivot_table 命令基本相同的输出(但希望更平坦、更整洁)?如果做不到这一点,我该如何展平pivot_table 的输出?我想要的输出更像是这样的:

firstname lastname weight     bike      car    plane                           
Amy       Frond    65.6886  27.101      NaN  344.200
Jon       Cho      81.0030  29.022  95.1144  302.952

【问题讨论】:

  • 所需的数据框是什么样的?
  • 如果你想要一个平面数据框,只需对 pivot_table 的结果执行.reset_index()

标签: python pandas


【解决方案1】:

如果你不想聚合pivot_table,你确实需要pivot函数。但是,pivot 不适用于提供多个索引列(实际上我不知道为什么)。但是,有一个类似于 pivot 的函数 unstack,它的工作原理相同,但基于(多)索引而不是列。

所以要使用这个,你可以先在结果中将你想要的列设置为索引/列标签作为索引:

df2 = df.set_index(['firstname','lastname','weight', 'vehicle'])

然后在最后一层取消堆叠(默认),以此类推“车辆”(成为列标签):

In [3]: df2.unstack()
Out[3]:
                             speed
vehicle                       bike      car    plane
firstname lastname weight
Amy       Frond    65.6886  27.101      NaN  344.200
Jon       Cho      81.0030  29.022  95.1144  302.952

如果您不想要多索引,您可以使用reset_index 将结果“展平”。
唯一可能遇到的问题是列也有两个级别,因此您可以先删除第一级,然后重置索引以成为一个真正扁平的数据框:

In [17]: df3 = df2.unstack()

In [18]: df3.columns = df3.columns.droplevel(0)

In [19]: df3.reset_index()
Out[19]:
vehicle firstname lastname   weight    bike      car    plane
0             Amy    Frond  65.6886  27.101      NaN  344.200
1             Jon      Cho  81.0030  29.022  95.1144  302.952

【讨论】:

  • 尽管索引现在是干净的,但我仍然获得了 df2.columns 的 MultiLevel
  • 你的意思是df3?你试过df3.columns = df3.columns.droplevel(0)
  • 它不太好用,因为所需的名称处于不同的级别。可能有一些泛泛的方法可以做到这一点,但我只是使用了列表理解和逻辑三元组。
  • 是的,这就是为什么你需要先降级,然后才重置索引。因为否则你最终会得到不同级别的所需名称。
猜你喜欢
  • 2018-12-19
  • 1970-01-01
  • 2018-09-19
  • 2021-11-15
  • 1970-01-01
  • 2018-09-23
  • 2021-12-28
  • 2021-06-30
  • 1970-01-01
相关资源
最近更新 更多