【发布时间】:2019-04-04 02:51:26
【问题描述】:
我有许多腌制的 pandas 数据帧,每个数据帧都有相当多的行数(~10k)。数据框的一列是一个 numpy ndarray 浮点数(是的,我特别选择将数组数据存储在单个单元格中 - 我读过这通常可能不是正确的方法,例如。here,但是在这种情况下,单个值是没有意义的,只有完整的值列表才有意义,所以我认为在这种情况下是有意义的)。我需要计算框架中每对行之间的欧几里得距离。我有这方面的工作代码,但我希望我能做一些事情来提高它的性能,因为现在它告诉我我的较小数据集将需要 > 一个月,但我很确定它需要在那之前我的所有记忆。
代码如下:
import pandas as pd
import sys
import getopt
import math
from scipy.spatial import distance
from timeit import default_timer as timer
from datetime import timedelta
id_column_1 = 'id1'
id_column_2 = 'id2'
distance_column = 'distance'
val_column = 'val'
# where n is the size of the set
# and k is the number of elements per combination
def combination_count(n, k):
if k > n:
return 0
else:
# n! / (k! * (n - k)!)
return math.factorial(n)/(math.factorial(k) * math.factorial(n - k))
def progress(start, current, total, id1, id2):
if current == 0:
print('Processing combination #%d of #%d, (%d, %d)' % (current, total, id1, id2))
else:
percent_complete = 100 * float(current)/float(total)
elapsed_time = timer() - start
avg_time = elapsed_time / current
remaining = total - current
remaining_time = timedelta(seconds=remaining * avg_time)
print('Processing combination #%d of #%d, (%d, %d). %.2f%% complete, ~%.2f s/combination, ~%s remaining' % (current, total, id1, id2, percent_complete, avg_time, remaining_time))
def check_distances(df):
indexes = df.index
total_combinations = combination_count(len(indexes), 2)
current_combination = 0
print('There are %d possible inter-message relationships to compute' % total_combinations)
distances = pd.DataFrame(columns=[id_column_1, id_column_2, distance_column])
distances.set_index([id_column_1, id_column_2], inplace=True)
start = timer()
for id1 in indexes:
for id2 in indexes:
# id1 is always < id2
if id1 >= id2:
continue
progress(start, current_combination, total_combinations, id1, id2)
distances.loc[(id1, id2), distance_column] = distance.euclidean(df.loc[id1, embeddings_column], df.loc[id2, embeddings_column])
current_combination+=1
(我排除了 main() 函数,它只是拉出 args 并根据它们加载到腌制文件中)
我最近才真正开始使用 Python 来完成这项任务,所以我很可能会遗漏一些简单的东西,有没有好的方法来处理这个问题?
【问题讨论】: