代码之家  ›  专栏  ›  技术社区  ›  D500

用最小距离计算曼哈顿距离返回类别

  •  2
  • D500  · 技术社区  · 6 年前

    我想创建一个函数来计算选定类别和数据集中所有其他类别之间的曼哈顿距离。然后,函数应返回与所选内容之间距离最小的类别。

    df = pd.DataFrame(np.random.randint(0,100, size= (10,4)), columns=list('ABCD'))
    df['category']= ['apple','orange','grape','berry','strawberry','banana','kiwi','lemon','lime','pear']
    

    下面的代码返回包含所选类别的最小4个距离(距离=0;这是冗余的,不需要)。我需要代码只返回最低的3个距离作为类别列表,第一个是最小的。

    def distance(row):
        cols = list('ABCD')
        return (df[cols] - row[cols]).abs().sum(axis=1)
    
    df.set_index('category', inplace=True)
    dist = df.apply(distance, axis=1)
    
    dist['apple'].nsmallest(4)
    

    例如,如果选择了“苹果”,并且距离苹果最远的三个距离分别是浆果、橘子和葡萄,则返回结果应如下所示:【浆果】、【橘子】、【葡萄】

    2 回复  |  直到 6 年前
        1
  •  0
  •   Mabel Villalba    6 年前

    一种选择是使用函数 cityblock scipy.spatial.distance :

    from scipy.spatial import distance
    
    df.set_index('category', inplace = True)
    
    >> df.apply(lambda x: distance.cityblock(x, df.loc['apple',:]), axis=1
            ).drop('apple', axis=1).nsmallest(4).index.values.tolist()
    
     ['strawberry', 'berry', 'kiwi', 'orange']
    

    基本上,您可以得到从每一行到所选行的距离。然后删除包含所选标签的行,并选择最小距离的索引。

        2
  •  1
  •   Brian    6 年前

    设置:

    df = pd.DataFrame(np.random.randint(0,100, size= (10,4)), columns=list('ABCD'))
    df['category']= . ['apple','orange','grape','berry','strawberry','banana','kiwi','lemon','lime','pear']
    df.set_index('category', inplace = True)
    

    这是一口,但是:

    lowest_3 = [df.index[pd.Series([abs(df.loc[ind1] - df.loc[ind2]).sum() for ind2 in df.index]).argsort()[1:4]].tolist() for ind1 in df.index]
    
    lowest_3_series = pd.Series(lowest_3, index = df.index)
    
    lowest_3_series['apple'] = ['banana', 'lemon', 'grape'] # Results will differ due to randomness obviously
    

    这将为您提供df.index中每个值的最低3个值的列表。

    例如,此列表的第一个元素是您的解决方案 'apple'

    说明:

    首先,为df.index中的每个索引创建一个列表理解。这个嵌套的列表理解再次是df.index的迭代。为此索引调用df并将它们全部进行比较(使n^2比较总数)。通过获取列值之间的绝对值并求和,可以比较每个索引。然后将此列表转换为一个系列并使用 argsort 获取前3个(不包括始终为0的自反比较)。然后在这个索引片上调用df.index,它将得到这些最低3个值的名称。