如何使用大型数据集并行化 python 循环



我正在尝试构建给定数据集的层次结构,其中每一行代表一个学生,他们参加的课程以及其他一些元数据。从这个数据集中,我试图构建一个邻接矩阵,并根据学生上过的课以及不同学生在选择课程时的路径来确定层次结构。

话虽如此,要构造这个邻接矩阵,它的计算成本很高。这是我目前拥有的代码,它已经运行了大约 2 个小时。

uniqueStudentIds = df.Id.unique()
uniqueClasses = df['Course_Title'].unique()
for studentID in uniqueStudentIds:
for course1 in uniqueClasses:
for course2 in uniqueClasses:
if (course1 != course2 and have_taken_both_courses(course1, course2, studentID)):
x = vertexDict[course1]
y = vertexDict[course2]
# Assuming symmetry
adjacency_matrix[x][y] += 1
adjacency_matrix[y][x] += 1
print(course1 + ', ' + course2)

def have_taken_both_courses(course1, course2, studentID):
hasTakenFirstCourse = len(df.loc[(df['Course_Title'] == course1) & (df['Id'] == studentID)]) > 0
if hasTakenFirstCourse:
return len(df.loc[(df['Course_Title'] == course2) & (df['Id'] == studentID)]) > 0
else:
return False

鉴于我的数据集非常大,我尝试在并行化/多线程化这个计算昂贵的 for 循环时查阅在线资源。但是,我是python和多处理的新手,因此任何指导将不胜感激!

它似乎循环的方式比你必须的要多。 对于每个学生,您进行NxN迭代,其中N是班级总数。 但是您的学生只参加了这些课程的一部分。 因此,您可以显著减少迭代次数。

您的 have_taken_both_courses(( 查找也比它需要的更昂贵。

像这样的事情可能会更快:

import numpy as np
import itertools
import pandas as pd
df = pd.read_table('/path/to/data.tsv')
students_df = pd.DataFrame(df['student'].unique())
students_lkp = {x[1][0]: x[0] for x in students_df.iterrows()}
classes_df = pd.DataFrame(df['class'].unique())
classes_lkp = {x[1][0]: x[0] for x in classes_df.iterrows()}
df['student_key'] = df['student'].apply(lambda x: students_lkp[x])
df['class_key'] = df['class'].apply(lambda x: classes_lkp[x])
df.set_index(['student_key', 'class_key'], inplace=True)
matr = np.zeros((len(classes_df), len(classes_df)))
for s in range(0, len(students_df)):
print s
# get all the classes for this student
classes = df.loc[s].index.unique().tolist()
for x, y in itertools.permutations(classes, 2):
matr[x][y] += 1

相关内容

  • 没有找到相关文章

最新更新