【问题标题】:Creating a hierarchical dictionary from DataFrame column从 DataFrame 列创建分层字典
【发布时间】:2020-07-06 21:01:13
【问题描述】:

我有一个这样的数据框;

+------------+------------+-------+
|    Date    | Total Cars | Lanes |  
+------------+------------+-------+
| 2019-10-20 |          5 |     2 |  
| 2019-10-23 |         15 |     3 |
| 2020-01-20 |         23 |     2 |
+------------+------------+-------+

我想返回这样的字典;

{
    "y2019":{
        "Year Total Cars":20,
        "Year Total Lanes":5,
        "M10":{
            "Month All Cars":20,
            "Month All Lanes":5,
            "Day20":{
                "Day All Cars":5,
                "Day All Lanes":2
            },
            "Day 23":{
                "Day All Cars":15,
                "Day All Lanes":3
            }
        }
    },
    "y2020":{
        "Year Total Cars":23,
        "Year Total Lanes":2,
        "M10":{
            "Month Total Cars":23,
            "Month Total Lanes":2,
            "Day20":{
                "Day All Cars":23,
                "Day All Lanes":2
            }
        }
    }
}

到目前为止,尝试使用 df.resample 并尝试从中创建嵌套字典,但没有成功。在 Pandas 中有没有其他优雅的方法来解决这个问题?

我尝试将日期解压缩到 Y-M-D 中并将它们添加到数据框中。然后我创建了一个 groupby 对象来迭代。

date_counter_df.loc[:,'year'] = [x.year for x in date_counter_df.index]
date_counter_df.loc[:,'month'] = [x.month for x in date_counter_df.index]
date_counter_df.loc[:,'day'] = [x.day for x in date_counter_df.index]

result = {}
for to_unpack, df_res in date_counter_df.groupby(['year','month','day']):
    year, month, day = to_unpack
    try:
        result[year]
    except KeyError:
        result[year] = {}
    try:
        result[year][month]
    except KeyError:
        result[year][month] = {}
    try:
        result[year][month][day]
    except KeyError:
        result[year][month][day] = {}

    result[year][month][day] = df_res

原始数据集的结果如下所示;

{2019: {10: {17:               sensor-id Totalt i retning Kristiansand Totalt i retning Oslo  \
   Date                                                                          
   2019-10-17  11219V22151                             0                     0   

                  1     2  3  4 Totalt Totalt i retning Fianex Rv 415  \
   Date                                                                 
   2019-10-17  2702  2615  0  0   5317                           2614   

              Totalt i retning Stølen X Rv 420  year  month  day  
   Date                                                           
   2019-10-17                             2703  2019     10   17  ,
   30:               sensor-id Totalt i retning Kristiansand Totalt i retning Oslo  \
   Date                                                                          
   2019-10-30  11219V22151                             0                     0   

                  1     2  3  4 Totalt Totalt i retning Fianex Rv 415  \
   Date                                                                 
   2019-10-30  2729  2589  0  0   5318                           2589   

              Totalt i retning Stølen X Rv 420  year  month  day  
   Date                                                           
   2019-10-30                             2729  2019     10   30  },
  12: {28:                 sensor-id Totalt i retning Kristiansand Totalt i retning Oslo  \
   Date                                                                            
   2019-12-28  61942V2809673                          3134                  3461   

                 1    2     3     4 Totalt Totalt i retning Fianex Rv 415  \
   Date                                                                     
   2019-12-28  333  494  2801  2967   6595                              0   

              Totalt i retning Stølen X Rv 420  year  month  day  
   Date                                                           
   2019-12-28                                0  2019     12   28  }},
 2020: {2: {19:                 sensor-id Totalt i retning Kristiansand Totalt i retning Oslo  \
   Date                                                                            
   2020-02-19  71445V2809674                          5006                  5202   

                 1    2     3     4 Totalt Totalt i retning Fianex Rv 415  \
   Date                                                                     
   2020-02-19  686  747  4320  4455  10208                              0   

              Totalt i retning Stølen X Rv 420  year  month  day  
   Date                                                           
   2020-02-19                                0  2020      2   19  }}}

现在我只需要将年份和月份的总数添加为 dict 项目。

【问题讨论】:

  • 我不知道优雅的方式。但是看看这个SO post
  • 为什么 2020 年的汽车总数是 12 而不是 23?
  • 这也是一个错字。修复。我还能够创建非常接近我想要的字典。感觉离答案很近了。 @sammywemmy

标签: python pandas dataframe dictionary


【解决方案1】:

Date 列到 Datetime 的转换开始(如果到现在 是字符串类型):

df.Date = pd.to_datetime(df.Date)

然后定义3个函数:

  1. 处理来自每月组的每一行的函数:

    def rowFn(row):
        return { 'Day All Cars': row['Total Cars'], 'Day All Lanes': row.Lanes }
    
  2. 处理每个月组的函数:

    def monthGrpFun(grp):
        dct = { 'Month All Cars': grp['Total Cars'].sum(),
                'Month All Lanes': grp.Lanes.sum() }
        for _, row in grp.iterrows():
            dct[f'Day {row.Date.day:02}'] = rowFn(row)
        return dct
    
  3. 处理每个年度组的函数:

    def yearGrpFun(grp):
        dct = { 'Year Total Cars': grp['Total Cars'].sum(),
                'Year Total Lanes': grp.Lanes.sum() }
        for key, grp2 in grp.groupby(grp.Date.dt.month):
            dct[f'M{key:02}'] = monthGrpFun(grp2)
        return dct
    

为了得到结果,运行:

dct = {}
for key, grp in df.groupby(df.Date.dt.year):
    dct[f'y{key}'] = yearGrpFun(grp)

您的数据的结果(为便于阅读而重新格式化)是:

{
  'y2019': {
    'Year Total Cars': 20,
    'Year Total Lanes': 5,
    'M10': {
      'Month All Cars': 20,
      'Month All Lanes': 5,
      'Day 20': {'Day All Cars': 5, 'Day All Lanes': 2},
      'Day 23': {'Day All Cars': 15, 'Day All Lanes': 3}
    }
  },
  'y2020': {
    'Year Total Cars': 23,
    'Year Total Lanes': 2,
    'M01': {
      'Month All Cars': 23,
      'Month All Lanes': 2,
      'Day 20': {'Day All Cars': 23, 'Day All Lanes': 2}
    }
  }
}

【讨论】:

    猜你喜欢
    • 2021-09-14
    • 2017-06-26
    • 2019-02-10
    • 2020-08-31
    • 1970-01-01
    • 2015-10-29
    • 2021-12-07
    • 2020-01-18
    • 2023-03-25
    相关资源
    最近更新 更多