Python 对pandas/matplotlib条形图中条形图的顺序进行排序

Python 对pandas/matplotlib条形图中条形图的顺序进行排序,python,matplotlib,pandas,Python,Matplotlib,Pandas,什么是Pythonic/pandas在pandas中对一列中的“级别”进行排序的方法,以给出条形图中条形图的特定顺序 例如,假设: import pandas as pd df = pd.DataFrame({ 'group': ['a', 'a', 'a', 'a', 'a', 'a', 'a', 'b', 'b', 'b', 'b', 'b', 'b', 'b'], 'day': ['Mon', 'Tues', 'Fri', 'Thurs', '

什么是Pythonic/pandas在pandas中对一列中的“级别”进行排序的方法,以给出条形图中条形图的特定顺序

例如,假设:

import pandas as pd
df = pd.DataFrame({
    'group': ['a', 'a', 'a', 'a', 'a', 'a', 'a', 
              'b', 'b', 'b', 'b', 'b', 'b', 'b'],
    'day': ['Mon', 'Tues', 'Fri', 'Thurs', 'Sat', 'Sun', 'Weds',
            'Fri', 'Sun', 'Thurs', 'Sat', 'Weds', 'Mon', 'Tues'],
    'amount': [1, 2, 4, 2, 1, 1, 2, 4, 5, 3, 4, 2, 1, 3]})
dfx = df.groupby(['group'])
dfx.plot(kind='bar', x='day')
我可以生成以下一对图:

条的顺序遵循行顺序

重新排列数据的最佳方式是什么,以便条形图上的条形图按顺序排列

更新:这个垃圾解决方案有效-但它使用额外的排序列的方式远远不够优雅:

df2 = pd.DataFrame({
    'day': ['Mon', 'Tues', 'Weds', 'Thurs', 'Fri', 'Sat', 'Sun'],
    'num': [0, 1, 2, 3, 4, 5, 6]})
df = pd.merge(df, df2, on='day')
df = df.sort_values('num')
dfx = df.groupby(['group'])
dfx.plot(kind='bar', x='day')
进一步概括:

是否有一种解决方案也可以修复“减淡”条形图中的条形顺序:

df.pivot('day', 'group', 'amount').plot(kind='bar')

您必须提供一个映射来指定如何对日期名称进行排序。(如果它们被存储为正确的日期,那么还有其他方法可以做到这一点。)

更新:

构建密钥。你可以明确地写一本字典,或者使用像这样聪明的字典

weekdays = ['Mon', 'Tues', 'Weds', 'Thurs', 'Fri', 'Sat', 'Sun']
mapping = {day: i for i, day in enumerate(weekdays)}
key = df['day'].map(mapping)
排序很简单:

df.iloc[key.argsort()]

我将提供下面的代码来扩展Dan的答案,以解决OP问题的“进一步概括”部分。首先,以Dan的解决方案为基础的简单案例(只有一个变量)的完整示例:

import pandas as pd

# Create dataframe 
df=pd.DataFrame({
    'group':['a','a','a','a','a','a','a','b','b','b','b','b','b','b'],
    'day':['Mon','Tues','Fri','Thurs','Sat','Sun','Weds','Fri','Sun','Thurs','Sat','Weds','Mon','Tues'],
    'amount':[1,2,4,2,1,1,2,4,5,3,4,2,1,3]
})


# Calculate the total amount for each day
df_grouped = df.groupby(['day']).sum().amount.reset_index()

# Use Dan's trick to order days names in the table created by groupby
weekdays = ['Mon', 'Tues', 'Weds', 'Thurs', 'Fri', 'Sat', 'Sun']
mapping = {day: i for i, day in enumerate(weekdays)}
key = df_grouped['day'].map(mapping)    
df_grouped = df_grouped.iloc[key.argsort()]

# Draw the bar chart
df_grouped.plot(kind='bar', x='day')
现在,我们使用相同的排序技术对数据透视表的行(而不是groupby创建的行)进行排序

结果如下所示:


我知道这个回复已经晚了,但是对于这两个案例,如果不使用字典/映射,那么一个简单的解决方案就是我在下面发布的内容

将“day”设置为索引使您能够使用.loc按特定顺序选择数据

1) 对于两个单独的地块

df=pd.DataFrame({'group':['a','a','a','a','a','a','a','b','b','b','b','b','b','b'],
     'day':['Mon','Tues','Fri','Thurs','Sat','Sun','Weds','Fri','Sun','Thurs','Sat','Weds','Mon','Tues'],
     'amount':[1,2,4,2,1,1,2,4,5,3,4,2,1,3]})

order = ['Mon', 'Tues', 'Weds','Thurs','Fri','Sat','Sun']`
df.set_index('day').loc[order].groupby('group').plot(kind='bar')
2) 对于具有减淡打印的轴示例:

order = ['Mon', 'Tues', 'Weds','Thurs','Fri','Sat','Sun']
df.pivot('day','group','amount').loc[order].plot(kind='bar')
请注意,pivot会导致day已经在索引中,因此您可以再次在此处使用.loc


编辑:在这些解决方案中,最好使用.loc而不是.ix。当列名和索引为数字时,.ix将被弃用,并可能产生奇怪的结果

我想得太多了。您所需要的只是
键和上面的简单一行。这不需要是df=df.iloc[key.argsort()]吗?这取决于您的解决方案是覆盖
df
还是成为一个新变量,例如
df1
。我让你决定。好的,谢谢;那么,如果我使用df.pivot('day','group','amount').plot(kind='bar')避开绘图,那么排序是如何工作的呢?排序丢失了吗?Dan-作为map()排序基础的dict理解是一个非常有用的技巧;感谢您将其添加到:-)闪避情节的第二个示例对我很有用。谢谢
order = ['Mon', 'Tues', 'Weds','Thurs','Fri','Sat','Sun']
df.pivot('day','group','amount').loc[order].plot(kind='bar')