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

时间:2018-10-03 14:29:03

标签: python pandas dataframe machine-learning

我正在寻找创建一个函数,该函数计算数据集中所选类别与所有其他类别之间的曼哈顿距离。然后,该函数应返回与所选内容距离最近的类别。

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)

例如,如果选择了“ Apple”,并且距苹果的三个最低距离是Berry,Orange和Grape,则返回应该像这样:[“ Berry”,“ Orange”,“ Grape”]

2 个答案:

答案 0 :(得分:1)

设置:

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个最低值的名称。

答案 1 :(得分:0)

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

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']

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