繁体   English   中英

为 Pandas Dataframe 中的两列创建稀疏矩阵

[英]Create sparse matrix for two columns in a Pandas Dataframe

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

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

表:类

    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

现在每个老师和学生都有一个与之关联的数字。 如果表class中出现student的数值,将teacher的数值存放在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)))

这适用于我的小型测试数据集。 然而,对于我实际的大型数据集,它崩溃了。

有没有更好的方法来做到这一点?

您可以将列转换为类别类型,然后使用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获取标签。

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

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()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM