python-3.x - 如何优化这个 python 脚本 Pandas 的时间?
问题描述
我有需要优化的脚本。示例数据在此处添加data。
我尝试了几件事,将 groupby 更改为使用排序值。我已经尝试过更快速地快速申请,但它需要更多时间。
df_loop = pd.read_excel("data.xlsx")
df_loop.index = df_loop["Destination"]
uni_list = df_loop["Destination"].unique()
def get_custcon(x):
dfa = df_loop[(df_loop.index.isin(x))]
dfa.sort_values\
(by = ["Source","Time"],ascending=True).drop_duplicates('Source'\
,keep='first',inplace = True)
return [x,dfa["con"].sum()/dfa["Options"].sum()]
def get_optimisation(site):
list_site = []
for si in range(site):
s = "step_" + str(si)
list_site.append(s)
list_site = ["random_combination"] + list_site + ["Cust"]
test_data = pd.DataFrame(columns = list_site)
Iteration = 1 #how many iteration do you want to run
for it in range(Iteration):
test_list = []
random_com = tuple(random.sample(set(df_loop["Source"]\
.unique()),site)) ### random combination
test_list.append(random_com)
for i in range(site):
li = list(range(site))
li.remove(i)
col_dict = {}
for k in li:
j = "site_" + str(k)
if j not in col_dict:
col_dict[j] = [random_com[k]]* 5
df_com = pd.DataFrame(col_dict)
df_com["site_"+str(i)] = uni_list
df_com["res"] = df_com.apply(lambda x : get_custcon(list(x)),axis = 1)
df_com[['combination', 'cust_C']] = df_com['res'].apply(pd.Series)
solution = df_com.loc[df_com["cust_C"].idxmin()][["res"]][0]
random_com = tuple(solution[0])
test_list.append(tuple(solution[0]))
test_list.append(solution[1])
test_data.loc[it] = test_list
return(test_data.loc[test_data["Cust"].idxmin()][test_data.columns[-2]])
start = time.time()
print(list(get_optimisation(2))) # write site number here
end = time.time()
print("time",end - start)
此代码通常需要 0.038 秒。现在我分享的数据只是样本。我有 250 万行的数据,它需要 75 秒,但我不能为这个过程腾出这么多时间。
我尝试过的代码但没有运气:
def get_custcon(x):
dfa = df_loop[(df_loop.index.isin(x))]
dfa.sort_values('Time').groupby('Source').first()
return [x,dfa["con"].sum()/dfa["Options"].sum()]
df_com["res"] = df_com.swifter.apply(lambda x : get_custcon(list(x)),axis = 1)
提前致谢。
解决方案
没有回顾为什么要嵌套 3 个 for 循环,因为您已经说过“慢”部分是get_custcon(x)
.
旁白:您可能会考虑是否需要嵌套,或者是否有办法在没有 3 个嵌套循环的情况下获得结果
看着get_custcon(x)
我看到您正在重复对过滤结果进行排序。我认为您可以排序一次,然后过滤:
df_loop_sorted = df_loop.copy()
df_loop_sorted.sort_values(by = ["Source","Time"], ascending=True).drop_duplicates('Source', keep='first', inplace = True)
def get_custcon(x):
dfa = df_loop_sorted[(df_loop_sorted["Destination"].isin(x))]
return [x,dfa["con"].sum()/dfa["Options"].sum()]
此更改将小数据的执行时间减少了一半。对于更大的数据,它可能更重要。
请注意,根据您可能需要的数据:
drop_duplicates(['Destination', 'Source'], keep='first', inplace=True)
推荐阅读
- java - 检查android手机存储中是否存在已知文档Uri
- spring-boot - 我可以使用 CriteriaQuery、CriteriaBuilder 从中使用 DTO 获取数据吗?
- python - Python:插入列表正在重写列表中的多个项目
- java - 通过具有 Lambda 代理集成的 API Gateway 从 AWS Lambda 引发错误
- flutter - 处理页面时如何从块中清除数据?
- python - 如何将语音输出添加到 Raspberry Pi 的 Tensorflow 对象检测 API?
- testing - Koin 模拟挂起功能
- c++ - C++ 自定义分配器大小参数作为模板参数引发编译器错误
- flutter - 如何在 Flutter 中自定义 TabBar 的指示器和标签?
- mysql - MySQL 局部变量值意外更改