函数在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
,也会有很大帮助。但请记住:您的代码正在分析大量数据。最小化搜索空间将是缩短运行时的主要因素。