Pandas透视表在添加列参数时按字母顺序排序分类数据(错误)

3 投票
1 回答
3031 浏览
提问于 2025-05-01 14:48

我在使用Pandas的透视函数时遇到了麻烦。我想按月份和年份来整理销售数据。数据集如下:

Customer - Sales - Month Name   - Year
a        - 100   - january      - 2013
a        - 120   - january      - 2014
b        - 220   - january      - 2013

为了能正确排序月份名称,我添加了一个包含月份名称的列,并把它设置为分类数据。

dataset['Month'] = dataset['Month Name'].astype('category')
dataset['Month'].cat.set_categories(['January', 'February', 'March', 'April', 'May', 'June',      'July', 'August', 'September', 'October', 'November', 'December'],inplace=True)
dataset.pop('Month Name')

当我使用这个函数时:

pt = dataset.pivot_table(values="Sales", index="Month")

我得到了预期的结果。

Month
January      3620302.79
February     3775507.25
March        4543839.69

但是,当我按年份和月份透视数据时,月份却是按字母顺序排序的。

print dataset.pivot_table(values='Sales', index="Month", columns="Year", aggfunc="sum")
Year            2011        2012        2013        2014
Month                                                   
April      833692.19   954483.28  1210847.85  1210926.61
August     722604.75   735078.52   879905.23  1207211.00
December   779873.51  1053441.71  1243745.73         NaN

我希望能得到一些帮助,让最后的代码示例中的月份名称能够正确排序。

谢谢,

Frank

暂无标签

1 个回答

0

你说得对,在使用 pivot_table 后,它会重新排列 'Month' 列,这样就会按字母顺序排序。幸运的是,你可以把 dataset['Month'] 转换成 pandas.datetime,然后在 pivot_table 重新排列后再转换回字符串。

这不是最好的解决办法,但应该能解决问题(我用了一些随机的示例):

import pandas as pd
...
# convert dataset['Month'] to pandas.datetime by the time of pivot
# it will reindex by datetime hence the sort order is kept
pivoted = dataset.pivot_table(index=pd.to_datetime(dataset['Month']), columns='Year', \
                              values='Sales', aggfunc='sum')
pivoted
Year        2012  2013  2014
Month                       
2014-01-04   151   295   NaN
2014-02-04   279   128   NaN
2014-03-04   218   244   NaN
2014-04-04   274   152   NaN
2014-05-04   276   NaN   138
2014-06-04   223   NaN   209
...

# then re-set the index back to Month string, "%B" means month string "January" etc.
pivoted.index = [pd.datetime.strftime(m, format='%B') for m in pivoted.index]

pivoted
Year       2012  2013  2014
January     151   295   NaN
February    279   128   NaN
March       218   244   NaN
April       274   152   NaN
May         276   NaN   138
June        223   NaN   209
...

不过,如果你需要 'Month' 的索引标签,你会发现它不见了。你可以把 dataset['Month'] 复制到另一列(叫它 M),然后转换成 datetime,接着在 pivot_table 上设置多个索引,像这样:

dataset.pivot_table(index=['M', 'Month'], ...)

撰写回答