在Pandas数据框中为两列创建稀疏矩阵

5

我正在尝试从Pandas数据集(>10Gb)中创建一个稀疏矩阵。

假设我有一个如下类型的数据集:

表:Class

    student |teacher
---------------------
0   | abc   |   a
1   | def   |   g

我有一份学生名单。
students = [ "abc", "def", "ghi", "jkl","mno"]

以及教师列表

teachers = ["a","b","c","d","e","f","g"]

我的目标是创建一个稀疏矩阵,如果表格Class中存在学生-教师对应关系,则矩阵中应该有一个布尔值1。

密集矩阵应该长这样:

    a   b   c   d   e   f   g

abc 1   0   0   0   0   0   0
def 0   0   0   0   0   0   1
ghi 0   0   0   0   0   0   0
jkl 0   0   0   0   0   0   0
mno 0   0   0   0   0   0   0

现在我的真实数据集中有70万个学生和10万个教师的数据。
最初,我尝试构建一个简单的密集矩阵,然后使用scipy将其转换为稀疏矩阵。然而,700k * 100k字节=约70GB,正如您所意识到的那样,这并不起作用。
因此,我尝试为学生和教师分配唯一值,然后将这些值附加到行和列,并尝试以坐标格式创建稀疏矩阵。
代码:
# Get unique value for each student and teacher
dictstudent = {}
count = 0
for i in rows:
    dictstudent[i] = count
    count +=1

dictteacher ={}
count = 0
for i in cols:
    dictteacher[i] = count
    count +=1

现在每位老师和学生都有一个与之关联的数字编号。如果学生出现在课程表中,请存储其数字值,如果教师出现在“r”和“c”表中,请存储其数字值。

r = []
c = []

for row,col in zip(student,teacher):
    r.append(dictstudent[row])
    c.append(dictteacher[col])

values = [1] * class["student"].size #From the pandas dataframe class

然后加载它以创建一个稀疏矩阵。
a = sparse.coo_matrix((values,(r,c)),shape=(len(students),len(teachers)))

这个方法对我的小测试数据集来说效果很好。但是对于我的实际大数据集,它崩溃了。

有更好的方法可以解决这个问题吗?

2个回答

3

您可以将列转换为类别类型,然后使用codes创建coo_matrix对象:

import numpy as np
import string
import random
import pandas as pd
from scipy import sparse

lowercase = list(string.ascii_lowercase)

students = np.random.choice(lowercase, size=[20, 3]).view("<U3").ravel().tolist()
teachers = np.random.choice(lowercase, 8).tolist()

df = pd.DataFrame({"student": [random.choice(students) for _ in range(30)],
                   "teacher": [random.choice(teachers) for _ in range(30)]})

df = df.apply(lambda s:s.astype("category"))
arr = sparse.coo_matrix((np.ones(df.shape[0]), 
    (df.student.cat.codes, df.teacher.cat.codes)))

您可以通过df.student.cat.categoriesdf.teacher.cat.categories来获取标签。

1

这是一个简单的方法来实现这个目标

import pandas as pd

dummies = pd.get_dummies(df['teacher'])
new_columns = dummies.columns
long_and_sparse = df.merge(dummies, left_index=True, right_index=True)
sparse_df = long_and_sparse.groupby(["student"], as_index=False)[new_columns].max()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接