Предположим, что у меня есть следующий словарь:
scenario_summary = {'Day1': {'22459-22585': 0.0, '22585-22711': 0.0, '22711-22837': 0.0, '22837-22963': 0.0, '22963-23089': 0.0, '23089-23215': 0.0, '23215-23341': 0.0, '23341-23467': 0.0, '23467-23593': 0.0, '23593-23719': 0.0, '23719-23845': 0.0, '23845-23971': 0.0, '23971-24097': 0.0, '24097-24223': 0.0, '24223-24349': 0.0, '24349-24475': 0.0, '24475-24601': 0.0, '24601-24727': 0.0, '24727-24853': 0.0, '24853-24979': 0.0, '24979-25105': 0.0, '25105-25231': 0.0, '25231-25357': 0.0, '25357-25483': 0.0, '25483-25609': 0.0, '25609-25735': 0.0, '25735-25861': 0.0, '25861-25987': 0.0, '25987-26113': 1.0, '26113-26239': 1.0, '26239-26365': 0.0, '26365-26491': 2.0, '26491-26617': 5.0, '26617-26743': 5.0, '26743-26869': 5.0, '26869-26995': 12.0, '26995-27121': 19.0, '27121-27247': 7.000000000000001, '27247-27373': 11.0, '27373-27499': 15.0, '27499-27625': 7.000000000000001, '27625-27751': 4.0, '27751-27877': 4.0, '27877-28003': 2.0, '28003-28129': 0.0, '28129-28255': 0.0, '28255-28381': 0.0, '28381-28507': 0.0, '28507-28633': 0.0, '28633-28759': 0.0, '28759-28885': 0.0, '28885-29011': 0.0, '29011-29137': 0.0, '29137-29263': 0.0, '29263-29389': 0.0, '29389-29515': 0.0, '29515-29641': 0.0, '29641-29767': 0.0, '29767-29893': 0.0, '29893-30019': 0.0, '30019-30145': 0.0, '30145-30271': 0.0, '30271-30397': 0.0, '30397-30523': 0.0, '30523-30649': 0.0, '30649-30775': 0.0, '30775-30901': 0.0, '30901-31027': 0.0, '31027-31153': 0.0, '31153-31279': 0.0, '31279-31405': 0.0, '31405-31531': 0.0, '31531-31657': 0.0, '31657-31783': 0.0, '31783-31909': 0.0, '31909-32035': 0.0, '32035-32161': 0.0, '32161-32287': 0.0, '32287-32413': 0.0, '32413-32539': 0.0, '32539-32665': 0.0, '32665-32791': 0.0, '32791-32917': 0.0, '32917-33043': 0.0, '33043-33169': 0.0, '33169-33295': 0.0, '33295-33421': 0.0, '33421-33547': 0.0, '33547-33673': 0.0, '33673-33799': 0.0, '33799-33925': 0.0, '33925-34051': 0.0, '34051-34177': 0.0, '34177-34303': 0.0, '34303-34429': 0.0, '34429-34555': 0.0, '34555-34681': 0.0, '34681-34807': 0.0}}
Как видите, словарь состоит из диапазона значений в строке и их частоты. Я хотел бы построить это как гистограмму, но я не знаю, как я смогу преобразовать строку в форму, которую поймут панды или сюжет. Каким будет ваш подход? Или есть более простой способ сделать это вместо жесткого кодирования? Или другой модуль был бы более простым вариантом?
Спасибо!
Вы можете использовать модуль pandas для преобразования данных словаря в фрейм данных:
import pandas as pd
import matplotlib.pyplot as plt
scenario_summary = {'Day1': {'22459-22585': 0.0, '22585-22711': 0.0, '22711-22837': 0.0,
'22837-22963': 0.0, '22963-23089': 0.0, '23089-23215': 0.0,
'23215-23341': 0.0, '23341-23467': 0.0, '23467-23593': 0.0,
'23593-23719': 0.0, '23719-23845': 0.0, '23845-23971': 0.0,
'23971-24097': 0.0, '24097-24223': 0.0, '24223-24349': 0.0,
'24349-24475': 0.0, '24475-24601': 0.0, '24601-24727': 0.0,
'24727-24853': 0.0, '24853-24979': 0.0, '24979-25105': 0.0,
'25105-25231': 0.0, '25231-25357': 0.0, '25357-25483': 0.0,
'25483-25609': 0.0, '25609-25735': 0.0, '25735-25861': 0.0,
'25861-25987': 0.0, '25987-26113': 1.0, '26113-26239': 1.0,
'26239-26365': 0.0, '26365-26491': 2.0, '26491-26617': 5.0,
'26617-26743': 5.0, '26743-26869': 5.0, '26869-26995': 12.0,
'26995-27121': 19.0, '27121-27247': 7.000000000000001, '27247-27373': 11.0,
'27373-27499': 15.0, '27499-27625': 7.000000000000001, '27625-27751': 4.0,
'27751-27877': 4.0, '27877-28003': 2.0, '28003-28129': 0.0,
'28129-28255': 0.0, '28255-28381': 0.0, '28381-28507': 0.0,
'28507-28633': 0.0, '28633-28759': 0.0, '28759-28885': 0.0,
'28885-29011': 0.0, '29011-29137': 0.0, '29137-29263': 0.0,
'29263-29389': 0.0, '29389-29515': 0.0, '29515-29641': 0.0,
'29641-29767': 0.0, '29767-29893': 0.0, '29893-30019': 0.0,
'30019-30145': 0.0, '30145-30271': 0.0, '30271-30397': 0.0,
'30397-30523': 0.0, '30523-30649': 0.0, '30649-30775': 0.0,
'30775-30901': 0.0, '30901-31027': 0.0, '31027-31153': 0.0,
'31153-31279': 0.0, '31279-31405': 0.0, '31405-31531': 0.0,
'31531-31657': 0.0, '31657-31783': 0.0, '31783-31909': 0.0,
'31909-32035': 0.0, '32035-32161': 0.0, '32161-32287': 0.0,
'32287-32413': 0.0, '32413-32539': 0.0, '32539-32665': 0.0,
'32665-32791': 0.0, '32791-32917': 0.0, '32917-33043': 0.0,
'33043-33169': 0.0, '33169-33295': 0.0, '33295-33421': 0.0,
'33421-33547': 0.0, '33547-33673': 0.0, '33673-33799': 0.0,
'33799-33925': 0.0, '33925-34051': 0.0, '34051-34177': 0.0,
'34177-34303': 0.0, '34303-34429': 0.0, '34429-34555': 0.0,
'34555-34681': 0.0, '34681-34807': 0.0}}
# convert to data frame
data_frame = pd.DataFrame.from_dict(scenario_summary)
# plot data
plt.hist(data_frame['Day1'], density=1, bins=20)
plt.show()
Вы видели значения x на графике? Это не выглядит правильно
Значения @Huzo x в порядке [0-19.0]
Они должны быть ключевыми значениями словаря. То есть каждый бин должен представлять такие значения, как 31909-32035 и т. д.
@Huzo, тогда вам не нужно использовать гистограмму. Гистограмма показывает наличие определенного диапазона элементов и нормализует его до наибольшего значения счетчика, которое в этом примере равно 0.
Гистограмма представляет собой простую столбчатую диаграмму, где каждый столбец представляет ячейку (обычно в виде диапазона) и частоту элементов, попадающих в эту ячейку.
Это именно те данные, которые у вас уже есть. Поэтому вместо значений вычисления для гистограммы (как это было бы сделано с plt.hist
) вы можете просто передать свои данные в plt.bar
, как есть. Результат будет таким:
Код с вашими данными, как MCVE :
import matplotlib.pyplot as plt
scenario_summary = { 'Day1': {
'22459-22585': 0.0, '22585-22711': 0.0, '22711-22837': 0.0,
'22837-22963': 0.0, '22963-23089': 0.0, '23089-23215': 0.0,
'23215-23341': 0.0, '23341-23467': 0.0, '23467-23593': 0.0,
'23593-23719': 0.0, '23719-23845': 0.0, '23845-23971': 0.0,
'23971-24097': 0.0, '24097-24223': 0.0, '24223-24349': 0.0,
'24349-24475': 0.0, '24475-24601': 0.0, '24601-24727': 0.0,
'24727-24853': 0.0, '24853-24979': 0.0, '24979-25105': 0.0,
'25105-25231': 0.0, '25231-25357': 0.0, '25357-25483': 0.0,
'25483-25609': 0.0, '25609-25735': 0.0, '25735-25861': 0.0,
'25861-25987': 0.0, '25987-26113': 1.0, '26113-26239': 1.0,
'26239-26365': 0.0, '26365-26491': 2.0, '26491-26617': 5.0,
'26617-26743': 5.0, '26743-26869': 5.0, '26869-26995': 12.0,
'26995-27121': 19.0, '27121-27247': 7.0, '27247-27373': 11.0,
'27373-27499': 15.0, '27499-27625': 7.0, '27625-27751': 4.0,
'27751-27877': 4.0, '27877-28003': 2.0, '28003-28129': 0.0,
'28129-28255': 0.0, '28255-28381': 0.0, '28381-28507': 0.0,
'28507-28633': 0.0, '28633-28759': 0.0, '28759-28885': 0.0,
'28885-29011': 0.0, '29011-29137': 0.0, '29137-29263': 0.0,
'29263-29389': 0.0, '29389-29515': 0.0, '29515-29641': 0.0,
'29641-29767': 0.0, '29767-29893': 0.0, '29893-30019': 0.0,
'30019-30145': 0.0, '30145-30271': 0.0, '30271-30397': 0.0,
'30397-30523': 0.0, '30523-30649': 0.0, '30649-30775': 0.0,
'30775-30901': 0.0, '30901-31027': 0.0, '31027-31153': 0.0,
'31153-31279': 0.0, '31279-31405': 0.0, '31405-31531': 0.0,
'31531-31657': 0.0, '31657-31783': 0.0, '31783-31909': 0.0,
'31909-32035': 0.0, '32035-32161': 0.0, '32161-32287': 0.0,
'32287-32413': 0.0, '32413-32539': 0.0, '32539-32665': 0.0,
'32665-32791': 0.0, '32791-32917': 0.0, '32917-33043': 0.0,
'33043-33169': 0.0, '33169-33295': 0.0, '33295-33421': 0.0,
'33421-33547': 0.0, '33547-33673': 0.0, '33673-33799': 0.0,
'33799-33925': 0.0, '33925-34051': 0.0, '34051-34177': 0.0,
'34177-34303': 0.0, '34303-34429': 0.0, '34429-34555': 0.0,
'34555-34681': 0.0, '34681-34807': 0.0}}
data = scenario_summary['Day1']
x = range(len(data))
y = list(data.values())
plt.figure(figsize=(16, 9))
plt.bar(x, y)
plt.subplots_adjust(bottom=0.2)
plt.xticks(x, data.keys(), rotation='vertical')
plt.show()
Поскольку bins (ranges)
уже определены, а их counts
уже агрегированы на уровне initial
, возможно, будет полезно, если вы создадите что-то, что накладывает histogram (distribution)
поверх существующих диапазонов bin
:
import matplotlib
%matplotlib inline
def plot_hist(bins,input_dict):
df1 = pd.DataFrame(input_dict).reset_index()
df1['min'] = df1['index'].apply(lambda x:x.split('-')[0]).astype(int)
df1['max'] = df1['index'].apply(lambda x:x.split('-')[1]).astype(int)
df1['group'] = pd.cut(df1['max'],bins,labels=False)
df2 = df1.groupby('group' [['Day1','min','max']].agg({'min':'min','max':'max','Day1':'sum'}).reset_index()
df2['range_new'] = df2['min'].astype(str) + str('-') + df2['max'].astype(str)
df2.plot(x='range_new',y='Day1',kind='bar')
... и вызовите функцию, выбрав бины меньше, чем length
словаря - или первый уровень из 98 бинов, которые уже есть, например, если вы хотите получить распределение из 20 групп:
plot_hist(20,scenario_summary)
Изображение результата :
Надеюсь, поможет...
Однако это создает несколько линейных графиков.