Nir*_*oda 0 optimization dataframe python-3.x pandas pandas-groupby
我有需要优化的脚本。示例数据添加到此处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)
Run Code Online (Sandbox Code Playgroud)
此代码通常需要 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)
Run Code Online (Sandbox Code Playgroud)
提前致谢。
无需回顾为什么要嵌套 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()]
Run Code Online (Sandbox Code Playgroud)
此更改将小数据的执行时间减少了一半。对于更大的数据来说,它可能更重要。
请注意,根据您可能需要的数据:
drop_duplicates(['Destination', 'Source'], keep='first', inplace=True)
Run Code Online (Sandbox Code Playgroud)