我有一个Python数据框架,它的列为paper, author, col_1, col_2, ..., col_100
Dtypes:
Paper type: string (unique)
Author type: string
col_x: float
我知道我要做的事情很复杂,而且性能很高,但我的解决方案需要花费很长时间才能完成
对于DataFrame中的每一行,我希望与该行中与author
不同的所有作者进行自联接。然后在col_x
的值中应用一个函数,并将上的每一行与另一行col_x
连接起来,并获得一些聚合结果
我的解决方案使用了我知道最慢的iterrows
,但我想不出任何其他方法
from sklearn.metrics.pairwise import cosine_similarity
from statistics import mean
papers = ... #is my dataframe
cols = ['min_col', 'avg_col', 'max_col', 'label']
all_cols = ['col_1', 'col_2', ..., 'col_100']
df_result = pd.DataFrame({}, columns = cols)
for ind, paper in papers.iterrows():
col_vector = paper[all_cols].values.reshape(1,-1) #bring the columns in the correct format
temp = papers[papers.author != paper.author].author.unique() #get all authors that are not the same with the one in the row
for auth in temp:
temp_papers = papers[papers.author == auth] #get all papers of that author
if temp_papers.shape[0] > 1: #if I have more than 1 paper find the cosine_similarity of the row and the joined rows
res = []
for t_ind, t_paper in temp_papers.iterrows():
res.append(cosine_similarity(col_vector, t_paper[all_cols].values.reshape(1,-1))[0][0])
df_result = df_result.append(pd.DataFrame([[min(res), mean(res), max(res), 0]], columns = cols), ignore_index = True)
第2版:
我还尝试对自身进行交叉连接,然后排除具有相同作者的行。然而,当我这样做时,我在几行中得到相同的错误
papers['key'] = 0['key'] = 0
cross = papers.merge(papers, on = 'key', how = 'outer')
>> [IPKernelApp] WARNING | No such comm: 3a1ea2fa71f711ea847aacde48001122
额外信息
数据帧的大小为45k行
大约有5千名独立作者
首先,如果数据帧不是太大(在您的例子中,它似乎太大),您可以通过使用
cosine_similarity
的矢量化来实现。要做到这一点,首先需要一个所有作者都有一行以上的掩码,创建一个数据框,在索引和列中包含足够的信息,以便能够分组,然后查询所需的行:第一个解决方案:
现在的问题是,有45K行和5K名作者,我怀疑普通计算机能否处理前面的方法。然后,我们的想法是执行相同的操作,但每个组作者:
注意:整个操作仍然很长,但在您的代码中,您在多个级别上降低了效率,如果您想保持
iterrows
,这里有几点可以提高代码的效率:iterrows
,但是两个iterrow加上另一个循环确实很慢iterrows
没有利用cosine_similarity
对于具有多个维度的输入数组被否决的优势temp = papers[papers.author != paper.author].author.unique()
是一个巨大的时间损失,可以在循环之前创建唯一作者列表,然后在循环中检查当前的paper.author
与auth
不同(使用您的符号)auth
之前都可以做if temp_papers.shape[0] > 1
,我假设纸张的数量没有变化,因此如果创建唯一的auth
外部循环列表(上一点),它可能已经不包括只有一篇论文的作者append
是一个巨大的时间损失,请参见this answer进行计时比较,因此最好创建另一个列表res_agg
,您可以这样做res_agg.append([min(res), mean(res), max(res), 0])
,在所有循环之后,df_result=pd.DataFrame(res_agg, columns=cols)
相关问题 更多 >
编程相关推荐