【问题标题】:creating new dataframe with manhattan distance in python在python中创建具有曼哈顿距离的新数据框
【发布时间】:2020-12-21 19:37:17
【问题描述】:

我需要创建一个数据框,其中包含具有相同列的两个数据框之间的曼哈顿距离,并且我需要每个数据框的索引作为索引和列名,例如,假设我有这两个数据框:

x_train :
index a b c
11    2 5 7
23    4 2 0
312   2 2 2
x_test : 
index a b c
22    1 1 1
30    2 0 0

所以列匹配但大小和索引不匹配,预期的数据框将如下所示:

dist_dataframe:
index 11 23 312
22    11 5  3
30    12 4  4

而我现在拥有的是这样的:

def manhattan_distance(a, b):
    return sum(abs(e1-e2) for e1, e2 in zip(a,b))

def calc_distance(X_test,X_train):
    dist_dataframe = pd.DataFrame(index=X_test.index,columns = X_train.index)
    for i in X_train.index:
        for j in X_test.index:
            dist_dataframe.loc[i,j]=manhattan_distance(X_train.loc[[i]],X_test.loc[[j]])
    return dist_dataframe

我从我拥有的代码中得到的是这个数据框:

dist_dataframe:
index
index 11  23  312
22    NaN NaN NaN
30    NaN NaN NaN

我得到了正确的数据框大小,除了它有 2 行称为索引,这是我从创建新数据框时获得的,而且无论我在曼哈顿计算行中做什么,我都会遇到错误,谁能帮帮我请在这里?

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    代码中的问题

    您的代码中有一个非常小的问题,即访问dist_dataframe 中的值。所以,你应该把 i 和 j 的顺序颠倒过来,而不是dist_dataframe.loc[i,j],让它像dist_dataframe.loc[j,i]

    更高效的解决方案

    它可以正常工作,但由于您是新的贡献者,我还想指出您的代码的效率。总是尝试用 pandas 内置函数替换循环。由于它们是用 C 编写的,因此它们的速度要快得多。所以这里有一个更有效的解决方案:

    def manhattan_distance(a, b):
        return sum(abs(e1-e2) for e1, e2 in zip(a,b))
    
    def xtrain_distance(row):
        distances = {}
        for i,each in x_train.iterrows():
            distances[i] = manhattan_distance(each,row)
        return distances
    
    result = x_test.apply(xtrain_distance, axis=1)
    
    # converting into dataframe
    pd.DataFrame(dict(result)).transpose()
    

    它也产生相同的输出,在您的示例中,您看不到任何时差。但是当在更大的尺寸(相同的数据缩放超过 20 倍)上运行时,即 60 个x_train 样本和 40 个x_test 样本,这里是时间差:

    您的解决方案采用:929 ms

    此解决方案采用:207 ms

    仅消除一个 for 循环,速度就提高了 4 倍。请注意,它可以提高效率,但为了演示,我使用了这个解决方案。

    【讨论】:

    • 谢谢,它成功了。我投了赞成票,但没有显示:/。还要感谢有关有效解决方案的提示!但我不确定我是否可以将它用于我的作业,因为我们不允许使用任何执行任何矢量距离函数的函数,不确定您的解决方案是否使用任何函数,很高兴知道
    • 嗨@bendush,该解决方案不使用任何涉及矢量化的函数。它只在 pandas 中使用 apply 方法,简单来说,沿任何轴有效地迭代数据帧,处理每个项目的函数,从而给出输出数据帧。为了更好地理解和比较矢量化方法,请参考:engineering.upside.com/…
    • 谢谢!我不明白你在 xtrain_distance 中得到的变量行是什么,如果你能解释一下,我将不胜感激!
    • 当然。当您在 pandas 中使用 apply 属性时,它会将函数名作为参数。然后它将数据帧的每一行(如果axis = 1)或每一列(如果axis = 0)作为输入传递给该函数。在我们的例子中,数据帧 x_test 的所有行都被一一传递给函数,输出是 pandas 一系列函数响应。
    猜你喜欢
    • 1970-01-01
    • 2012-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-09
    相关资源
    最近更新 更多