Конвертировать Pandas DF в формат JSON - PullRequest
0 голосов
/ 28 сентября 2018

У меня есть датафрейм в пандах следующей формы:

# df name: cust_sim_data_product_agg:
yearmo  region  products    revenue
0   201711  CN  ['Auto', 'Flood', 'Home', 'Liability', 'Life',...   690
1   201711  CN  ['Auto', 'Flood', 'Home', 'Liability', 'Life']  610
2   201711  CN  ['Auto', 'Flood', 'Home', 'Liability']  560
3   201711  CN  ['Auto', 'Flood', 'Home', 'Life', 'Liability',...   690
4   201711  CN  ['Auto', 'Flood', 'Home', 'Life', 'Mortgage', ...   690

Я бы хотел свернуть его во вложенный json формы:

{
  yearmo: '201711'
  data: [
    {
      name: 'SE',
      value: 18090, # sum of all the values in the level below
      children: [
        {
          name: '['Auto', 'Flood', 'Home',...], # this is product from the dataframe
          value: 690 . # this is the revenue value
        },
        {
          name: '['Flood', 'Home', 'Life'...],
          value: 690
        },
        ...
      },
      {
      name: 'NE',
      value: 16500, # sum of all the values in the level below
      children: [
        {
          name: '['Auto', 'Home',...],
          value: 210
        },
        {
          name: '['Life'...],
          value: 450
        },
        ...
      }
    },
  yearmo: '201712'
  data: [
    {
      name: 'SE',
      value: 24050,
      children: [ ... ] # same format as above
    },
    {
      name: 'NE',
      value: 22400,
      children: [ ... ] # same format as above
    }
  ]
}

Так каждый годбудет иметь элемент на верхнем уровне JSON.Внутри данных будет запись для каждого региона, где значение - это сумма значений уровня, находящегося непосредственно под ним.Children - это массив диктов, где каждый диктует карту продукта -> имя и доход -> значение из данных уровня строки в pandas DF.

Моя лучшая попытка на данный момент выглядит следующим образом:

def roll_yearmo_rev(d):
    x1 = [{'name': n, 'value': v}  for n,v in zip(d.products, d.revenue)]
    x2 = {'children': x1, 'value': sum(d.revenue)}
    return x2

def roll_yearmo(d):
    x1 = [{'name': n, 'children': c} for n,c in zip(d.region, d.children)]
    x2 = {'children': x1, 'value': sum(d.value)}
    return x2

cust_sim_data_product_agg_dict = cust_sim_data_product_agg.groupby(['yearmo', 'region'])\
    .apply(roll_yearmo_rev)
cust_sim_data_product_agg_dict = cust_sim_data_product_agg_dict.reset_index()
cust_sim_data_product_agg_dict.columns = ['yearmo' , 'region', 'children']


cust_sim_data_product_agg_dict = cust_sim_data_product_agg_dict.groupby(['yearmo'])\
    .apply(roll_yearmo)
cust_sim_data_product_agg_dict = cust_sim_data_product_agg_dict.reset_index()

Который терпит неудачу, потому что последний накопительный пакет выдает следующую ошибку:

AttributeError: 'DataFrame' object has no attribute 'value'

Все это выглядит мне грязно.Я читал о split-apply-объединении, которое вдохновило использование groupby () и apply (), но я мог бы действительно использовать второе мнение о подходе, потому что я почти уверен, что есть лучший способ.Любой совет будет оценен.

...