【发布时间】:2021-08-28 11:56:40
【问题描述】:
我有一个模拟,它使用熊猫数据框来描述层次结构中的对象。为此,我使用了 MultiIndex 来显示到子对象的路径。
父 df
par_val
a b
0 0.0 0.366660
1.0 0.613888
1 2.0 0.506531
3.0 0.327356
2 4.0 0.684335
0.0 0.013800
3 1.0 0.590058
2.0 0.179399
4 3.0 0.790628
4.0 0.310662
儿童 df
child_val
a b c
0 0.0 0 0.528217
1.0 0 0.515479
1 2.0 0 0.719221
3.0 0 0.785008
2 4.0 0 0.249344
0.0 0 0.455133
3 1.0 0 0.009394
2.0 0 0.775960
4 3.0 0 0.639091
4.0 0 0.150854
0 0.0 1 0.319277
1.0 1 0.571580
1 2.0 1 0.029063
3.0 1 0.498197
2 4.0 1 0.424188
0.0 1 0.572045
3 1.0 1 0.246166
2.0 1 0.888984
4 3.0 1 0.818633
4.0 1 0.366697
这意味着子 Dataframe 中的对象 (0,0,0) 和 (0,0,1) 都由父 Dataframe 中的 (0,0) 处的值来表征。
当对“a”的某个主题的子数据帧执行函数时,它可能需要从“b”中获取一个值。我当前的解决方案通过 solution 函数中的索引从父 Dataframe 中定位值:
import pandas as pd
import numpy as np
import time
from matplotlib import pyplot as plt
r = range(10, 1000, 10)
dt = []
for i in r:
start = time.time()
df_par = pd.DataFrame(
{'a': np.repeat(np.arange(5), i/5),
'b': np.append(np.arange(i/2), np.arange(i/2)),
'par_val': np.random.rand(i)
}).set_index(['a','b'])
df_child = pd.concat([df_par[[]]] * 2, keys = [0, 1], names = ['c'])\
.reorder_levels(['a', 'b', 'c'])
df_child['child_val'] = np.random.rand(i * 2)
df_child['solution'] = np.nan
def solution(row, df_par, var):
data_level = len(df_par.index.names)
index_filt = tuple([row.name[i] for i in range(data_level)])
sol = df_par.loc[index_filt, 'par_val'] / row.child_val
return sol
a_mask = df_child.index.get_level_values('a') == 0
df_child.loc[a_mask, 'solution'] = df_child.loc[a_mask].apply(solution,
df_par = df_par,
var = 10,
axis = 1)
stop = time.time()
dt.append(stop - start)
plt.plot(r, dt)
plt.show()
对于模拟中的大量迭代,求解函数变得非常昂贵:
(迭代次数 (x) 与以秒为单位的时间 (y))
有没有更有效的计算方法?我曾考虑在子 df 中包含“par_val”,但我试图避免这种情况,因为大量重复会减少我可以放入 RAM 中的模拟量。
【问题讨论】:
标签: python pandas dataframe performance