【发布时间】:2018-11-20 22:29:52
【问题描述】:
我得到了类似这个的 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
我正在尝试实现一种方法,当给定数据集中的索引时,它将从数据集中返回相似的项目(以某种合理的方式)。现在我有:
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
此方法获取您的行,然后从数据框中的每一行中减去它,然后计算每一行的范数。所以这个方法只是使用欧几里德距离返回一系列离你给定点最近的点。
因此,您可以获得最接近的 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) 相同(但除此之外的任何东西都可能变得不合理)
【问题讨论】:
-
如果您计划预先计算所有数据点的最近点,我建议您使用 Apache Spark,它为您提供针对此类用例的开箱即用并行处理。事实上,它几乎没有用于类似工作的内置方法。例如:它已经有一个推荐系统的 ALS
-
很难概括 w.r.t. Q1 和 Q2。在某种程度上,您正在对同质类型的规则形状数组中的数据进行纯粹的数字处理,numpy 将比 pandas 快很多(请注意,我添加了一个 numpy 标记 btw)。所以我会从寻找好的基于 numpy 的方法开始。除此之外,也许看看 numba、numexpr、cython。