У меня есть данные состояний и классов, как показано ниже. Я пытаюсь построить общий график и разные проценты, используя matplotlib.
data = [['FL', 2], ['AR', 0], ['CA', 0], ['CA', 1], ['AR', 1], ['FL', 0], ['CA', 0], ['CA', 1], ['AR', 2], ['FL', 1],
['AR', 0], ['FL', 2], ['CA', 1], ['FL', 1], ['AR', 1], ['AR', 2], ['AR', 1], ['FL', 2], ['CA', 2], ['FL', 0],
['FL', 2], ['AR', 2], ['AR', 1], ['FL', 0], ['AR', 1], ['CA', 0], ['CA', 0], ['CA', 2]]
columns = ['State', 'Class']
df = pd.DataFrame(data=data, columns=columns)
df.groupby(['State', 'Class']).size()
Подсчеты были построены с использованием кода ниже:
df.groupby(['State', 'Class']).size().to_frame('Size').unstack(level=-1).sort_values([('Size', 0)], ascending=False).plot(kind='bar', rot=45, figsize=(8,8), fontsize=10)
plt.legend(['Class 0', 'Class 1', 'Class 2'], prop = {'size' : 15})
Точно так же необходимо нанести проценты (на уровне штата, на уровне класса и в целом). Вот что я ищу:
Не могли бы вы помочь с тем, как это можно сделать с элегантным подходом?
Ниже мое текущее решение. Нужно построить StatePercent, ClassPercent и TotalPercent (рис. 3). Я хочу сгенерировать 3 графика без создания столбцов, как это делается для «Размера» (рис. № 2). (В реальном фрейме данных у меня есть сотни других столбцов, поэтому ищу варианты, чтобы не создавать ненужные столбцы, если это возможно. Эти три столбца нужны только для статистики, а не для какой-либо обработки)
PiC# 1 - фрейм данных
Рис № 2 — построение «Размера» без создания столбца в df
Рис № 3. Необходимо построить значения StatePercent, ClassPercent и TotalPercent, как рассчитано ниже.
Здравствуйте, relent95, извините за неясность. У меня есть решение; но я считаю его совсем новичком. Так что я здесь, в stakoverflow, за экспертным мнением и элегантными подходами. Вот как я это сейчас рисую. df = df.groupby(['State', 'Class']).size().reset_index(name='Size') df['StatePercent'] = df.groupby('State')['Size'].transform(lambda x: x/sum(x)) df['ClassPercent'] = df.groupby('Class')['Size'].transform(lambda x: x/sum(x)) df['OverallPercent'] = df['Size'].transform(lambda x:x/sum(x)) Я думаю, что есть гораздо лучшие способы построения графика без создания столбцов. Пожалуйста, помогите. Спасибо.
Вам нужно добавить этот код в свой вопрос. Также вам нужно определить свои термины. Например, «процент на уровне состояния» для состояния и класса может быть определен как 100*(количество записей для штата и класса)/(количество записей для класса и всех состояний).
Я предполагаю, что ваши термины определены так.
Вы можете использовать apply() и sum(), как в следующем примере.
df0 = df.groupby(['State', 'Class']).size().to_frame('Size')
df1 = df0.unstack(level=1).apply(lambda row: 100*row/sum(row), axis=1)
df2 = df0.unstack(level=0).apply(lambda row: 100*row/sum(row), axis=1)
df3 = 100*df0.unstack(level=1)/df0.sum().sum()
Вы можете построить df1, df2 и df3 для случаев 1, 2 и 3 соответственно.
См. Как спросить и минимальный воспроизводимый пример. Непонятно «проценты (уровень штата, уровень класса и в целом)», и вы должны сначала попытаться запрограммировать это самостоятельно. В любом случае, почему вы сначала ищете «элегантный»? Просто сначала решите проблему с помощью основных инструментов. Вы сказали «проценты». Почему бы не получить какие-то суммы с помощью DataFrame.sum() или DataFrameGroupBy.sum() и разделить значения?