У меня есть датафрейм в пандах следующей формы:
# 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 (), но я мог бы действительно использовать второе мнение о подходе, потому что я почти уверен, что есть лучший способ.Любой совет будет оценен.