熊猫多索引数据透视表已转换为字典列表

时间:2020-03-17 21:12:39

标签: python pandas

我有一个非常具体的问题,想用Pandas解决。

给出以下形式的输入数据框:

    item_id customer_id  year   A    B
0         0       cust1  2020  10  100
1         0       cust1  2021  11  101
2         0       cust1  2022  12  102
3         1       cust1  2020  20  200
4         1       cust1  2021  21  201
5         1       cust1  2022  22  202
6         0       cust2  2020  30  300
7         0       cust2  2021  31  301
8         0       cust2  2022  32  302
9         1       cust2  2020  40  400
10        1       cust2  2021  41  401
11        1       cust2  2022  42  402

我想将该数据框转换为以下列表:

[ 
  { "item_id": 0, 
    "customer_id": "cust1", 
    "A": [10,11,12],
    "B": [100, 101, 102],
  },
  ...
}

我觉得自己快到了,自然也想无循环地解决它。我最接近的解决方案是:

import pandas as pd

df = pd.DataFrame({
    'item_id': [0, 0, 0, 1, 1, 1]*2,
    'customer_id': ['cust1']*6 + ['cust2']*6,
    'year': [2020,2021,2022]*4,
    'A': [10, 11, 12, 20, 21, 22, 30, 31, 32, 40, 41, 42],
    'B': [100, 101, 102, 200, 201, 202, 300, 301, 302, 400, 401, 402],
})

df_pivot = df.pivot_table(
    values=['A','B'],
    columns='year',
    index=['item_id', 'customer_id']).reset_index()

# closest approach
df_pivot.T.groupby(level=0).apply(lambda df: df.xs(df.name).to_dict('list')).to_dict()

# will result in
# { 'A': { 0: [10,11,12], ...}
#.  'B': { 0: [100, 101, 102], ...}
#.  'customer_id': { 0: ['cust1'], ...}
#.  'item_id': [0: [0], ...}
#. }

...关闭,但仍然需要循环。有什么好主意吗?

2 个答案:

答案 0 :(得分:2)

这是groupby()to_dict

(df.groupby(['item_id','customer_id'])
   .agg(list).reset_index()
   .to_dict('row')
)

输出:

[{'item_id': 0,
  'customer_id': 'cust1',
  'year': [2020, 2021, 2022],
  'A': [10, 11, 12],
  'B': [100, 101, 102]},
 {'item_id': 0,
  'customer_id': 'cust2',
  'year': [2020, 2021, 2022],
  'A': [30, 31, 32],
  'B': [300, 301, 302]},
 {'item_id': 1,
  'customer_id': 'cust1',
  'year': [2020, 2021, 2022],
  'A': [20, 21, 22],
  'B': [200, 201, 202]},
 {'item_id': 1,
  'customer_id': 'cust2',
  'year': [2020, 2021, 2022],
  'A': [40, 41, 42],
  'B': [400, 401, 402]}]

答案 1 :(得分:2)

GroupBy.aggas_index=FalseDataFrame.to_dict()一起使用

df.groupby(['item_id','customer_id'],
           as_index=False)['A','B'].agg(list).to_dict('records')

输出

[{'item_id': 0,
  'customer_id': 'cust1',
  'A': [10, 11, 12],
  'B': [100, 101, 102]},
 {'item_id': 0,
  'customer_id': 'cust2',
  'A': [30, 31, 32],
  'B': [300, 301, 302]},
 {'item_id': 1,
  'customer_id': 'cust1',
  'A': [20, 21, 22],
  'B': [200, 201, 202]},
 {'item_id': 1,
  'customer_id': 'cust2',
  'A': [40, 41, 42],
  'B': [400, 401, 402]}]
相关问题