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

如何用大数据集并行化python循环,python,pandas,parallel-processing,multiprocessing,Python,Pandas,Parallel Processing,Multiprocessing,我试图在给定数据集的情况下构建层次结构,其中每一行代表一个学生、他们所学的课程以及一些其他元数据。从这个数据集中,我试图构造一个邻接矩阵,并根据学生所上的课以及不同学生在选择课时所走的路径来确定层次结构 这就是说,要构造这个邻接矩阵,计算代价很高。这是我目前拥有的代码,已经运行了大约2个小时 uniqueStudentIds = df.Id.unique() uniqueClasses = df['Course_Title'].unique() for studentID in uniqueSt

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

这就是说,要构造这个邻接矩阵,计算代价很高。这是我目前拥有的代码,已经运行了大约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是类的总数。但是你的学生只上了这些课程的一小部分。因此,您可以显著减少迭代次数

你已经修了两门课()查找的费用也比实际需要的要高

像这样的事情可能会快得多:

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

看来你已经不必这么做了。对于您进行NxN迭代的每个学生,其中N是类的总数。但是你的学生只上了这些课程的一小部分。因此,您可以显著减少迭代次数

你已经修了两门课()查找的费用也比实际需要的要高

像这样的事情可能会快得多:

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

在sql中这样做可能会更好。你只是在寻找所有的课程x,y,这样就有一个学生同时修了x和y?要注意的一点是使用集合而不是列表。虽然我希望在SQL中这样做,但我需要构造矩阵,然后进行一些数据格式化,以将数据导入API。我不知道该怎么做,因为我的数据文件是CSV,我最终必须返回一个表示图形的json对象。实际上,你正在对每个唯一的对进行线性扫描,以获得计数,每次都进行重复迭代。这:
len(df.loc[(df['Course\u Title']==course1)和(df['Id']==studentID)])>0
在您的紧密循环中非常昂贵。并行化不会像提高计数效率那样有帮助。另外,如果您想在唯一id上循环,只需转换为列表,而不使用numpy数组。您最好在sql中这样做。你只是在寻找所有的课程x,y,这样就有一个学生同时修了x和y?要注意的一点是使用集合而不是列表。虽然我希望在SQL中这样做,但我需要构造矩阵,然后进行一些数据格式化,以将数据导入API。我不知道该怎么做,因为我的数据文件是CSV,我最终必须返回一个表示图形的json对象。实际上,你正在对每个唯一的对进行线性扫描,以获得计数,每次都进行重复迭代。这:
len(df.loc[(df['Course\u Title']==course1)和(df['Id']==studentID)])>0
在您的紧密循环中非常昂贵。并行化不会像提高计数效率那样有帮助。另外,如果你想在唯一id上循环,只需转换为列表,不要使用numpy ArrayShanks!这肯定会快得多。只是一些语义上的东西。在底部,x和y,这些数字代表什么?这些是类的代理键。i、 e.
classes\u df
中类的索引,当我想在扫描矩阵后检索行的元数据时,给定类的键索引,我将使用什么命令?
classes\u df.loc[x]
其中
x
是您要查找的键!这肯定会快得多。只是一些语义上的东西。在底部,x和y,这些数字代表什么?这些是类的代理键。i、 e.
classes\u df
中类的索引,当我想在扫描矩阵后检索行的元数据时,给定class\u键索引,我将使用什么命令?
classes\u df.loc[x]
其中
x
是您要查找的键