熊猫-DateTime分组依据结构化字典

时间:2019-04-30 20:37:55

标签: python pandas

我有一个包含DateTime字段的数据集。我需要按hours进行分组,并将每个组分发到具有以下结构的字典:

{year_1: 
    {month_1: 
        {week_1: 
            {day_1: 
                {hour_1: df_1, hour_2: df_2}
            }
        },
        {week_2: 
            {day_1: 
                {hour_1: df_1}
            }
        }
    },
    {month_3: 
        {week_1: 
            {day_1: 
                {hour_1: df_1, hour_2: df_2}
            }
        }
    },
year_2:
    {month_5: 
        {week_1: 
            {day_1: 
                {hour_2: df_2}
            }
        }
    }
}

为此,我正在使用以下代码:

import pandas as pd

df = df = pd.DataFrame({'date': [pd.datetime(2015,3,17,2),    pd.datetime(2014,3,24,3), pd.datetime(2014,3,17,4)], 'hdg_id': [4041,4041,4041],'stock': [1.0,1.0,1.0]})
df.loc[:,'year'] = [x.year for x in df['date']]
df.loc[:,'month'] = [x.month for x in df['date']]
df.loc[:,'week'] = [x.week for x in df['date']]
df.loc[:,'day'] = [x.day for x in df['date']]
df.loc[:,'hour'] = [x.hour for x in df['date']]

result = {}
for to_unpack, df_hour in df.groupby(['year','month','day','week','hour']):
    year, month, week, day, hour = to_unpack
    try:
        result[year]
    except KeyError:
        result[year] = {}
    try:
        result[year][month]
    except KeyError:
        result[year][month] = {}
    try:
        result[year][month][week]
    except KeyError:
        result[year][month][week] = {}
    try:
        result[year][month][week][day]
    except KeyError:
        result[year][month][week][day] = {}

    result[year][month][week][day][hour] = df_hour

如您所见,这几乎是一种蛮力解决方案,而我一直在寻找更干净,更易理解的东西。此外,它也非常慢。我尝试了不同的分组方式(Python Pandas Group by date using datetime data),还尝试了对日期时间的每个组成部分(Pandas DataFrame with MultiIndex: Group by year of DateTime level values)进行多重处理。但是,问题始终是如何创建字典。理想情况下,我只想编写如下内容:

result[year][month][week][day][hour] = df_hour

但是据我所知,我首先需要初始化每个字典。

1 个答案:

答案 0 :(得分:4)

您需要dict.setdefault

result = {}
for to_unpack, df_hour in df.groupby(['year','month','day','week','hour']):
    year, month, week, day, hour = to_unpack

    result.setdefault(year, {}) \
          .setdefault(month, {}) \
          .setdefault(week, {}) \
          .setdefault(day, {}) \
          .setdefault(hour, df_hour)

您也可以将dict子类化

class Fict(dict):
    def __getitem__(self, item):
        return super().setdefault(item, type(self)())

result = Fict()

for to_unpack, df_hour in df.groupby(['year','month','day','week','hour']):
    year, month, week, day, hour = to_unpack

    result[year][month][week][day][hour] = df_hour