如何按中位数对熊猫的箱线图进行排序?

Fre*_*d S 13 python boxplot pandas

我想按类别和Z数据在数据框中绘制一个列的方框图.如何按中位数按降序对箱线图进行排序?dfXY

import pandas as pd
import random
n = 100
# this is probably a strange way to generate random data; please feel free to correct it
df = pd.DataFrame({"X": [random.choice(["A","B","C"]) for i in range(n)], 
                   "Y": [random.choice(["a","b","c"]) for i in range(n)],
                   "Z": [random.gauss(0,1) for i in range(n)]})
df.boxplot(column="Z", by=["X", "Y"])
Run Code Online (Sandbox Code Playgroud)

请注意,这个问题非常相似,但它们使用不同的数据结构.我对pandas比较陌生(并且一般只在python上做了一些教程),所以我无法弄清楚如何使我的数据与那里发布的答案一起工作.这可能更像是重塑而不是绘图问题.也许有一个解决方案使用groupby

Alv*_*tes 15

您可以使用如何按照pandas中间值对boxplot排序,但首先需要对数据进行分组并创建新的数据框:

import pandas as pd
import random
import matplotlib.pyplot as plt

n = 100
# this is probably a strange way to generate random data; please feel free to correct it
df = pd.DataFrame({"X": [random.choice(["A","B","C"]) for i in range(n)], 
                   "Y": [random.choice(["a","b","c"]) for i in range(n)],
                   "Z": [random.gauss(0,1) for i in range(n)]})
grouped = df.groupby(["X", "Y"])

df2 = pd.DataFrame({col:vals['Z'] for col,vals in grouped})

meds = df2.median()
meds.sort(ascending=False)
df2 = df2[meds.index]
df2.boxplot()

plt.show()
Run Code Online (Sandbox Code Playgroud)

情节

  • 我必须将``meds.sort(ascending = False)`更改为``meds.sort_values(ascending = False,inplace = True)`才能工作(熊猫0.20.1,Python 3.6.1,Windows 8)。 (2认同)

J W*_*ang 12

函数形式的xndrme类似的答案,更具可移植性

import pandas as pd

def boxplot_sorted(df, by, column):
  df2 = pd.DataFrame({col:vals[column] for col, vals in df.groupby(by)})
  meds = df2.median().sort_values()
  df2[meds.index].boxplot(rot=90)

boxplot_sorted(df, by=["X", "Y"], column="Z")
Run Code Online (Sandbox Code Playgroud)


roc*_*ves 7

要回答标题中的问题,而不涉及绘制两个分类变量的所有组合的额外细节:

n = 100
df = pd.DataFrame({"Category": [np.random.choice(["A","B","C","D"]) for i in range(n)],      
                   "Variable": [np.random.normal(0, 10) for i in range(n)]})

grouped = df.loc[:,['Category', 'Variable']] \
    .groupby(['Category']) \
    .median() \
    .sort_values(by='Variable')

sns.boxplot(x=df.Category, y=df.Variable, order=grouped.index)

Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

我添加了这个解决方案是因为很难将接受的答案减少到单个变量,而且我相信人们正在寻找一种方法来做到这一点。我自己多次来到这个问题寻找这样的答案。