Pandas 数据框使用应用或矢量化将列转换为 json 列
Pandas dataframe transform columns to json columns using apply or vectorization
下面是来自 sql 的给定数据帧,例如:
id
days
type
delta
A
B
1
30
X
1
0.1
0.5
1
30
Y
2
0.2
0.6
1
60
X
1
0.3
0.7
1
60
Y
2
0.4
0.8
转换数据框,我想达到这样的效果:
id
day_30
day_60
1
{A: {X1: 01, Y2: 0.2}, B: {X1: 0.5, Y2: 0.6}
{A: {X1: 0.3, Y2: 0.4}, B: {X1: 0.7, Y2: 0.8}
目前我可以通过按 Id 分组,然后按天分组并执行 iterrows 来实现。但是对于数百万行来说它非常慢。我怎样才能让它更快任何应用或矢量化示例来做同样的事情都会非常有帮助。
当前代码:
grp = df.groupby('id')
row_list = []
for name, df_grp in grp:
o_row = [id]
day_grp = df_grp.groupby('days')
for d_name, df_day_grp:
a_dict = {}
b_dict = {}
for idx, row in df_day_grp.iterrows():
a_dict[f'{row['type']}{row['delta']}] = row['A']
b_dict[f'{row['type']}{row['delta']}] = row['B']
row_dict = { 'A': a_dict, 'B': b_dict }
o_row.append(json_dumps(row_dict))
row_list.append(o_row)
df = pd.DataFrame(row_list, columns=cols)
我猜创建新数据框和使用 iterrows 可能是速度缓慢的原因。
有任何想法吗?我如何通过使用应用或分配来实现类似的效果?
首先加入 type
与 delta
与 DataFrame.pop
for use and remove column delta
, then use custom lambda function per groups in GroupBy.apply
for create nested dictionaries and last reshape by Series.unstack
with DataFrame.add_prefix
:
c = ['A','B']
df['type'] = df['type'] + df.pop('delta').astype(str)
f = lambda x: x.set_index('type')[c].to_dict()
df = df.groupby(['id','days']).apply(f).unstack().add_prefix('day_').reset_index()
print (df)
days id day_30 \
0 1 {'A': {'X1': 0.1, 'Y2': 0.2}, 'B': {'X1': 0.5,...
days day_60
0 {'A': {'X1': 0.3, 'Y2': 0.4}, 'B': {'X1': 0.7,...
下面是来自 sql 的给定数据帧,例如:
id | days | type | delta | A | B |
---|---|---|---|---|---|
1 | 30 | X | 1 | 0.1 | 0.5 |
1 | 30 | Y | 2 | 0.2 | 0.6 |
1 | 60 | X | 1 | 0.3 | 0.7 |
1 | 60 | Y | 2 | 0.4 | 0.8 |
转换数据框,我想达到这样的效果:
id | day_30 | day_60 |
---|---|---|
1 | {A: {X1: 01, Y2: 0.2}, B: {X1: 0.5, Y2: 0.6} | {A: {X1: 0.3, Y2: 0.4}, B: {X1: 0.7, Y2: 0.8} |
目前我可以通过按 Id 分组,然后按天分组并执行 iterrows 来实现。但是对于数百万行来说它非常慢。我怎样才能让它更快任何应用或矢量化示例来做同样的事情都会非常有帮助。
当前代码:
grp = df.groupby('id')
row_list = []
for name, df_grp in grp:
o_row = [id]
day_grp = df_grp.groupby('days')
for d_name, df_day_grp:
a_dict = {}
b_dict = {}
for idx, row in df_day_grp.iterrows():
a_dict[f'{row['type']}{row['delta']}] = row['A']
b_dict[f'{row['type']}{row['delta']}] = row['B']
row_dict = { 'A': a_dict, 'B': b_dict }
o_row.append(json_dumps(row_dict))
row_list.append(o_row)
df = pd.DataFrame(row_list, columns=cols)
我猜创建新数据框和使用 iterrows 可能是速度缓慢的原因。 有任何想法吗?我如何通过使用应用或分配来实现类似的效果?
首先加入 type
与 delta
与 DataFrame.pop
for use and remove column delta
, then use custom lambda function per groups in GroupBy.apply
for create nested dictionaries and last reshape by Series.unstack
with DataFrame.add_prefix
:
c = ['A','B']
df['type'] = df['type'] + df.pop('delta').astype(str)
f = lambda x: x.set_index('type')[c].to_dict()
df = df.groupby(['id','days']).apply(f).unstack().add_prefix('day_').reset_index()
print (df)
days id day_30 \
0 1 {'A': {'X1': 0.1, 'Y2': 0.2}, 'B': {'X1': 0.5,...
days day_60
0 {'A': {'X1': 0.3, 'Y2': 0.4}, 'B': {'X1': 0.7,...