Построение гистограммы с использованием диапазона значений и их частоты в качестве словаря - PullRequest
4 голосов
/ 27 мая 2019

Предположим, у меня есть следующий словарь:

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}}

Как видите, словарь состоит из диапазона значений в строке и их частоты. Я хотел бы представить это как гистограмму, но я не знаю, как бы я смог преобразовать строку в форму, которую панды или сюжет поняли бы. Каким будет ваш подход? Или есть более простой способ сделать это вместо жесткого кодирования? Или другой модуль был бы более легким вариантом для этого?

Спасибо!

Ответы [ 3 ]

1 голос
/ 27 мая 2019

Гистограмма - это в основном простая гистограмма, где каждый столбец представляет ячейку (обычно в форме диапазона) и частоту элементов, попадающих в эту ячейку.

Это именно данныечто у вас уже есть.Таким образом, вместо вычисления значений для гистограммы (как это было бы сделано с plt.hist), вы можете просто передать свои данные в plt.bar, как есть .Тогда результат будет таким:

Histogram

Код с вашими данными, как 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()
1 голос
/ 27 мая 2019

Поскольку 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)

Изображение результата :

image

надеюсь, это поможет ...

1 голос
/ 27 мая 2019

Вы можете использовать модуль 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()
...