我得到8000x3数据集,类似于这个数据集:
import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.rand(8000,3), columns=list('XYZ'))因此,作为视觉参考,df.head(5)如下所示:
X Y Z
0 0.462433 0.559442 0.016778
1 0.663771 0.092044 0.636519
2 0.111489 0.676621 0.839845
3 0.244361 0.599264 0.505175
4 0.115844 0.888622 0.766014我正在尝试实现一个方法,当从dataset获得索引时,它将从dataset返回类似的项(以某种合理的方式)。现在我有:
def find_similiar_items(item_id):
tmp_df = df.sub(df.loc[item_id], axis='columns')
tmp_series = tmp_df.apply(np.square).apply(np.sum, axis=1)
tmp_series.sort()
return tmp_series此方法接受您的行,然后从dataframe中的彼此行中减去它,然后计算每一行的范数。因此,这个方法只是使用欧几里德距离将一系列最近的点返回给你的给定点。
因此,您可以得到最近的5分,例如:
df.loc[find_similiar_items(5).index].head(5)产生的结果:
X Y Z
5 0.364020 0.380303 0.623393
4618 0.369122 0.399772 0.643603
4634 0.352484 0.402435 0.619763
5396 0.386675 0.370417 0.600555
3229 0.355186 0.410202 0.616844这个方法的问题是,每次调用它大约需要半秒钟。对于我的目的来说,这是不可接受的,所以我需要弄清楚如何在某种程度上提高这个方法的性能。所以我有几个问题:
问题1,,是否有一种更有效的方法来简单地计算上面的欧几里德距离?
问题2,还有其他一些技术,可以得到这样合理的结果(例如,欧几里德距离并不重要)。在这个问题中,计算时间比内存更重要,而预处理时间并不重要;因此,例如,我愿意构造一个大小与笛卡儿积(n^2)相同的原始数据(但任何比这更不合理的数据)。
发布于 2015-05-28 12:47:17
你最大的(也是最简单的)表现可能是仅仅在矮胖的熊猫身上做这个。从代码快速转换到numpy,我看到了超过200倍的改进:
arr = df.values
def fsi_numpy(item_id):
tmp_arr = arr - arr[item_id]
tmp_ser = np.sum( np.square( tmp_arr ), axis=1 )
return tmp_ser
df['dist'] = fsi_numpy(5)
df = df.sort_values('dist').head(5)
X Y Z dist
5 0.272985 0.131939 0.449750 0.000000
5130 0.272429 0.138705 0.425510 0.000634
4609 0.264882 0.103006 0.476723 0.001630
1794 0.245371 0.175648 0.451705 0.002677
6937 0.221363 0.137457 0.463451 0.002883检查它是否给出与您的函数相同的结果(因为我们有不同的随机抽签):
df.loc[ pd.DataFrame( find_similiar_items(5)).index].head(5)
X Y Z
5 0.272985 0.131939 0.449750
5130 0.272429 0.138705 0.425510
4609 0.264882 0.103006 0.476723
1794 0.245371 0.175648 0.451705
6937 0.221363 0.137457 0.463451计时:
%timeit df.loc[ pd.DataFrame( find_similiar_items(5)).index].head(5)
1 loops, best of 3: 638 ms per loop
In [105]: %%timeit
...: df['dist'] = fsi_numpy(5)
...: df = df.sort_values('dist').head(5)
...:
100 loops, best of 3: 2.69 ms per loophttps://stackoverflow.com/questions/30490147
复制相似问题