如何在数据透视后对python中数据框中的索引列以外的列进行排序

Posted

技术标签:

【中文标题】如何在数据透视后对python中数据框中的索引列以外的列进行排序【英文标题】:How to sort columns except index column in a data frame in python after pivot 【发布时间】:2021-11-11 04:53:24 【问题描述】:

所以我有一个数据框

testdf = pd.DataFrame("loc" : ["ab12","bc12","cd12","ab12","bc13","cd12"], "months" : 
         ["Jun21","Jun21","July21","July21","Aug21","Aug21"], "dept" : 
         ["dep1","dep2","dep3","dep2","dep1","dep3"], "count": [15, 16, 15, 92, 90, 2])

看起来像这样:

当我旋转它时,

df =  pd.pivot_table(testdf, values = ['count'], index = ['loc','dept'], columns = ['months'], aggfunc=np.sum).reset_index()
df.columns = df.columns.droplevel(0)
df

看起来像这样:

我正在寻找一个排序函数,它只会按顺序对月份列进行排序,而不是前 2 列,即 loc & dept。

当我尝试这个时:

df.sort_values(by = ['Jun21'],ascending = False, inplace = True, axis = 1, ignore_index=True)[2:]

它给了我错误。

我希望列按 Jun21、Jul21、Aug21 的顺序排列

我正在寻找可以使其动态化的东西,并且我不需要在月份变化时手动更改顺序。

任何提示将不胜感激。

【问题讨论】:

这能回答你的问题吗? Sorting month columns in pandas pivot_table 检查我的答案@Ruchika 【参考方案1】:

如果你使用 groupby 就很简单

df = testdf.groupby(['loc', 'dept', 'months']).sum().unstack(level=2)
df = df.reindex(['Jun21', 'July21', 'Aug21'], axis=1, level=1)

输出

          count             
months    Jun21 July21 Aug21
loc  dept                   
ab12 dep1  15.0    NaN   NaN
     dep2   NaN   92.0   NaN
bc12 dep2  16.0    NaN   NaN
bc13 dep1   NaN    NaN  90.0
cd12 dep3   NaN   15.0   2.0

【讨论】:

【参考方案2】:

我们可以先将months 列转换为datetime,如下所示:

>>> testdf.months = (pd.to_datetime(testdf.months, format="%b%y", errors='coerce'))
>>> testdf
    loc     months      dept    count
0   ab12    2021-06-01  dep1    15
1   bc12    2021-06-01  dep2    16
2   cd12    2021-07-01  dep3    15
3   ab12    2021-07-01  dep2    92
4   bc13    2021-08-01  dep1    90
5   cd12    2021-08-01  dep3    2

然后,我们应用您的代码来获取pivot

>>> df =  pd.pivot_table(testdf, values = ['count'], index = ['loc','dept'], columns = ['months'], aggfunc=np.sum).reset_index()
>>> df.columns = df.columns.droplevel(0)
>>> df
months  NaT     NaT     2021-06-01  2021-07-01  2021-08-01
0       ab12    dep1    15.0        NaN         NaN
1       ab12    dep2    NaN         92.0        NaN
2       bc12    dep2    16.0        NaN         NaN
3       bc13    dep1    NaN         NaN         90.0
4       cd12    dep3    NaN         15.0        2.0

最后,我们可以使用strftime 重新格式化列名以获得预期结果:

>>> df.columns = df.columns.map(lambda t: t.strftime('%b%y') if pd.notnull(t) else '')
>>> df
months                  Jun21   Jul21   Aug21
0       ab12    dep1    15.0    NaN     NaN
1       ab12    dep2    NaN     92.0    NaN
2       bc12    dep2    16.0    NaN     NaN
3       bc13    dep1    NaN     NaN     90.0
4       cd12    dep3    NaN     15.0    2.0

【讨论】:

对不起,我的错。那是一个错字。我只有 Jul21 之类的。但这里的问题是,这个解决方案只重命名列,而不是对整个列进行排序。像 Aug 的值被分配给 Jun。 啊好吧,解决我的朋友是最具挑战性的部分。其余的答案是否解决了您的问题?如果是这样,请不要犹豫,验证答案并投票;) 哦,你是对的!我会看的! 我更新了答案,现在它按预期保存了与列关联的正确数据! 谢谢!是的,我认为这会奏效。我还在上面,现在它给了我一个错误“AttributeError:'str'对象没有属性'strftime'”

以上是关于如何在数据透视后对python中数据框中的索引列以外的列进行排序的主要内容,如果未能解决你的问题,请参考以下文章

如何提取/拆分数据框中的列表列以分隔唯一列?

透视列以填充另一列中的值

循环遍历数据框中的列以按类别生成直方图

遍历 pandas 数据框中的所有列以在分隔符上拆分

在 Pandas 数据框中过滤多个列以获取相同的字符串

将数据解析/反透视到熊猫数据框中的列中