【发布时间】:2016-03-11 10:12:37
【问题描述】:
即使我发现一些处理距离矩阵效率的线程,它们都使用 int 或 float 矩阵。在我的例子中,我必须处理向量(orderedDict of frequency),而我最终只能得到一个非常慢的方法,这种方法对于大型 DataFrame(300,000 x 300,000)是不可行的。
如何让流程更优化?
非常感谢您的帮助,这个问题一直困扰着我:)
考虑DataFrame df 如:
>>> df
vectors
id
1 {dict1}
2 {dict2}
3 {dict3}
4 {dict4}
{dict#}在哪里
orderedDict{event1: 1,
event2: 5,
event3: 0,
...}
返回两个向量之间距离的函数:
def vectorDistance(a, b, df_vector):
# Calculate distance between a & b
# based on the vector from df_vector.
return distance
[in]: vectorDistance({dict1}, {dict2})
[out]: distance
所需的输出:
1 2 3 4
id
1 0 1<->2 1<->3 1<->4
2 1<->2 0 ... ...
3 1<->3 ... 0 ...
4 1<->4 ... ... 0
(其中 12 是向量 1 和 2 之间的浮点距离)
使用方法:
import pandas as pd
matrix = pd.concat([df, df.T], axis=1)
for index in matrix.index:
for col in matrix.columns:
matrix.ix[col, index] = vectorDistance(col, index, df)
>>> matrix
5072142538 5072134420 4716823618 ...
udid
5072142538 0.00000 0.01501 0.06002 ...
5072134420 0.01501 0.00000 0.09037 ...
4716823618 0.06002 0.09037 0.00000 ...
... ... ... ...
编辑:
小例子
注意:事件可以从一个 {dict} 到另一个不同,但在函数中传递时没关系。我的问题更多是如何通过正确的 a & b 快速填充单元格。
我正在处理余弦距离,因为它与我的向量等向量相当好。
from collections import Counter
import pandas as pd
from math import sqrt
raw_data = {'counters_': {4716823618: Counter({51811: 1, 51820: 1, 51833: 56, 51835: 8, 51843: 48, 51848: 2, 51852: 8, 51853: 5, 51854: 4, 51856: 24, 51903: 11, 51904: 12, 51905: 3, 51906: 19, 51908: 230, 51922: 24, 51927: 19, 51931: 2, 106282: 9, 112830: 1, 119453: 1, 165062: 80, 168904: 3, 180354: 19, 180437: 33, 185824: 117, 186171: 14, 187101: 1, 190827: 7, 201629: 1, 209318: 37}), 5072134420: Counter({51811: 1, 51812: 1, 51820: 1, 51833: 56, 51835: 9, 51843: 49, 51848: 2, 51852: 11, 51853: 4, 51854: 4, 51856: 28, 51885: 1, 51903: 17, 51904: 17, 51905: 9, 51906: 14, 51908: 225, 51927: 29, 51931: 2, 106282: 19, 112830: 2, 168904: 9, 180354: 14, 185824: 219, 186171: 7, 187101: 1, 190827: 6, 201629: 2, 209318: 41}), 5072142538: Counter({51811: 4, 51812: 4, 51820: 4, 51833: 56, 51835: 8, 51843: 48, 51848: 2, 51852: 6, 51853: 3, 51854: 3, 51856: 18, 51885: 1, 51903: 17, 51904: 16, 51905: 3, 51906: 24, 51908: 258, 51927: 20, 51931: 8, 106282: 16, 112830: 2, 168904: 3, 180354: 24, 185824: 180, 186171: 10, 187101: 1, 190827: 7, 201629: 2, 209318: 52})}}
def vectorDistance(index, col):
a = dict(df[df.index == index]["counters_"].values[0])
b = dict(df[df.index == col]["counters_"].values[0])
return abs(np.round(1-(similarity(a,b)),5))
def scalar(collection):
total = 0
for coin, count in collection.items():
total += count * count
return sqrt(total)
def similarity(A,B):
total = 0
for kind in A:
if kind in B:
total += A[kind] * B[kind]
return float(total) / (scalar(A) * scalar(B))
df = pd.DataFrame(raw_data)
matrix = pd.concat([df, df.T], axis=1)
matrix.drop("counters_",0,inplace=True)
matrix.drop("counters_",1,inplace=True)
for index in matrix.index:
for col in matrix.columns:
matrix.ix[col,index] = vectorDistance(col,index)
matrix
【问题讨论】:
-
每部字典是否有相同的事件,或者它们可以不同?您可能还需要提供 vectorDistance 函数的详细信息,以便其他人可以复制结果。
-
嗨@Alexander,对不起,我不小心按了 Enter,我在问题中添加了您需要的详细信息,因为它很长 :)
-
大概有多少独特的事件?只是想知道计算每对之间的距离并进行查找是否可行。
-
1000左右,不过让我用真实数据做一个最小的示例文件,我会添加问题的链接,应该不会太长。
-
@Alexander,你去吧,我添加了具有实际值的最小示例。如果您能找到解决方案,期待您阅读。
标签: performance pandas matrix vector distance