Piy*_*ush 5 python matrix scipy sparse-matrix pandas
我正在尝试从 Pandas 数据集(>10Gb)创建稀疏矩阵
假设我有一个类型的数据集
表:类别
student |teacher
---------------------
0 | abc | a
1 | def | g
Run Code Online (Sandbox Code Playgroud)
我有一份学生名单
students = [ "abc", "def", "ghi", "jkl","mno"]
Run Code Online (Sandbox Code Playgroud)
以及教师名单
teachers = ["a","b","c","d","e","f","g"]
Run Code Online (Sandbox Code Playgroud)
我的目标是创建一个稀疏矩阵,如果表 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
Run Code Online (Sandbox Code Playgroud)
现在,在我的真实数据集中,我有 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
Run Code Online (Sandbox Code Playgroud)
现在每个老师和学生都有一个与之关联的数字。如果学生的数值出现在表类中,则将其存储,而教师的数值则存储在 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
Run Code Online (Sandbox Code Playgroud)
然后加载它来制作稀疏矩阵
a = sparse.coo_matrix((values,(r,c)),shape=(len(students),len(teachers)))
Run Code Online (Sandbox Code Playgroud)
这对于我的小型测试数据集效果很好。然而,对于我实际的大型数据集,它崩溃了。
有一个更好的方法吗?
您可以将列转换为类别类型,然后使用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)))
Run Code Online (Sandbox Code Playgroud)
df.student.cat.categories您可以通过和获取标签df.teacher.cat.categories。