函数在Python中运行时间长-效率高
我有两个数据帧函数在Python中运行时间长-效率高,python,pandas,Python,Pandas,我有两个数据帧 df1 = pd.DataFrame({'a': [1.5, 2.5], 'b': [0.25, 2.75], 'c': [1.25, 0.75], 'd': [1.5, 2.5],'e': [0.25, 2.75], 'f': [1.25, 0.75]}) df2 = pd.DataFrame({'a': [1.5, 2.5,3.5,4.5], 'b': [0.25, 1.5, 2.5, 2.75], 'c': [1.25, 0.75, 3.5, 4.5], 'd': [1.
df1 = pd.DataFrame({'a': [1.5, 2.5], 'b': [0.25, 2.75], 'c': [1.25, 0.75], 'd': [1.5, 2.5],'e': [0.25, 2.75], 'f': [1.25, 0.75]})
df2 = pd.DataFrame({'a': [1.5, 2.5,3.5,4.5], 'b': [0.25, 1.5, 2.5, 2.75], 'c': [1.25, 0.75, 3.5, 4.5], 'd': [1.5, 2.5, 3.5, 4.5],'e': [0.25, 2.75, 1.5, 3.5], 'f': [1.25, 0.75, 2.5, 4.5]})
对于df1中的每一行,我想找到该行与特定列的所有df2行之间的距离。在找到距离之后,我想找到所有行中该行的最小距离,并返回df2的相应“e”值
例如,如果我传递a列和b列,对于df1的每一行,我想找到df2中所有行的a和b之间的距离,找到所有行的最小距离,并得到df2的相应“e”值
我正在使用以下两个功能
def distance(x1, x2, L):
start_time = time.time()
dist = (np.sum((np.array(x1)-np.array(x2))**L))**(1/(float(L)))
print("Time taken: " + str(round(time.time() - start_time,2)) + " seconds")
return dist
def mindistance(data1,data2,variables,L):
start_time = time.time()
pred_values=[]
test1=[]
for index2, row2 in data2.iterrows():
test=[]
for index1, row1 in data1.iterrows():
a=distance(row2[variables],row1[variables],L)
test.append(a)
#print(test)
index=test.index(min(test))
#print(index)
b=round(data1['e'].iloc[index],2)
pred_values.append(b)
print(pred_values)
print(len(pred_values))
return "Time taken: " + str(round(time.time() - start_time,2)) + " seconds"
print mindistance(df2, df1,['a','b'],2)
这些功能运行良好。但是在这段代码中有一个巨大的效率问题。距离部分花了很长时间。假设基于我的原始数据帧,我有大约60000次迭代需要完成,那么计算它需要一分钟以上的时间。我尝试了逐行调试,大部分时间都花在
a=distance(row2[variables],row1[variables],L)
line中。有人能帮我提高代码的效率吗?下面是如何使用apply
重写mindistance函数的方法
def mindistance(data1,data2,variables,L):
start_time = time.time()
pred_values=[]
test1=[]
for index2, row2 in data2[variables].iterrows():
test=list( data1[variables].apply( distance, args=(row2,L,), axis=1 ) )
index=test.index(min(test))
#print index
b=round(data1['e'].iloc[index],2)
pred_values.append(b)
#print pred_values
#print len(pred_values)
return "Time taken: " + str(round(time.time() - start_time,2)) + " seconds"
这将带来实质性的改善。您还可以进一步将另一个循环转换为对apply
的调用。您对代码进行了分析吗?如果您使用apply
而不是显式地迭代数据帧,会发生什么情况?@PaulH很抱歉,我是python新手。不确定什么是评测,不知道如何使用apply函数?你能帮我做这件事吗?评测python代码:使用apply
这是因为你的代码本身很长:对于每一行,你必须像其他行一样采样(O(n)
时间复杂度,这意味着每一行的运行时间与数据帧的大小成正比),这意味着你的总运行时间是O(n^2)
。由于row1检查row2==row2检查row1,您可以删除冗余并获得O(n*log(n))
time。使用矢量化代码,例如apply
,也会有很大帮助。但请记住:您的代码正在分析大量数据。最小化搜索空间将是缩短运行时的主要因素。