You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何对行列数不同的scipy.sparse稀疏矩阵实现类外连接合并?

问题描述

我有多个scipy.sparse.csr_matrix类型的稀疏矩阵,这些矩阵是按user_id分组后,用CountVectorizer处理文本生成的,所有矩阵的行数总和等于原数据集data的行数。现在需要把它们合并成一个形状为(总行数, 所有矩阵列数之和)的矩阵——即把所有行拼接起来,同时每个矩阵的行在其他矩阵的列位置补0(类似外连接效果)。但由于各矩阵的行、列数均不相同,无法直接使用vstack或hstack方法,寻求解决方案。

原生成矩阵的代码如下:

import pandas as pd
from sklearn.feature_extraction.text import CountVectorizer
from local_utils import get_data


def _count_words_within_userid(x):
        model = CountVectorizer(min_df=1, ngram_range=(1, 2), binary=True)
        transformed_data = model.fit_transform(x)
        return transformed_data 


data = get_data()

user_models_and_data = data.groupby("user_id")["text"].apply(_count_words_within_userid)

矩阵合并效果示例:

m1 = [[0,0,1],
     [0,1,0]]

m2 = [[0,1],
      [1,1],
      [1,0]]

result = some_function((m1,m2))

# 前3列来自m1,后2列来自m2。
# m2的行拼接到m1的行之后,在m1的列位置填充0;
# m1的行在m2的列位置填充0,最终形状为`(m1.rows+m2.rows, m1.columns+m2.columns)`

print(result)

#  [[0,0,1,0,0],
#   [0,1,0,0,0],
#   [0,0,0,0,1],
#   [0,0,0,1,1],
#   [0,0,0,1,0]
#   ]
解决方案

核心思路:先给每个稀疏矩阵补全对应其他矩阵列数的0列,让所有矩阵的列数统一为总列数,再垂直拼接所有矩阵。

步骤实现

  1. 提取所有稀疏矩阵,统计总列数
  2. 对每个矩阵,拼接原矩阵和对应行数的0矩阵(补全剩余列数)
  3. 垂直拼接所有处理后的矩阵,得到最终结果

完整代码如下:

import pandas as pd
from sklearn.feature_extraction.text import CountVectorizer
from scipy.sparse import csr_matrix, hstack, vstack
from local_utils import get_data


def _count_words_within_userid(x):
        model = CountVectorizer(min_df=1, ngram_range=(1, 2), binary=True)
        transformed_data = model.fit_transform(x)
        return transformed_data 


data = get_data()
user_models_and_data = data.groupby("user_id")["text"].apply(_count_words_within_userid)

# 提取所有稀疏矩阵
sparse_matrices = list(user_models_and_data.values)
# 计算所有矩阵的总列数
total_cols = sum(mat.shape[1] for mat in sparse_matrices)

# 处理每个矩阵,补全0列
processed_matrices = []
for mat in sparse_matrices:
    mat_rows, mat_cols = mat.shape
    # 需要补充的0列数
    zero_col_count = total_cols - mat_cols
    # 创建对应行数的稀疏0矩阵
    zero_mat = csr_matrix((mat_rows, zero_col_count), dtype=mat.dtype)
    # 水平拼接原矩阵和0矩阵,得到列数统一的矩阵
    processed_mat = hstack([mat, zero_mat])
    processed_matrices.append(processed_mat)

# 垂直拼接所有处理后的矩阵,得到最终结果
final_matrix = vstack(processed_matrices)

# 验证示例(可选)
def test_merge_example():
    m1 = csr_matrix([[0,0,1], [0,1,0]])
    m2 = csr_matrix([[0,1], [1,1], [1,0]])
    test_matrices = [m1, m2]
    test_total_cols = sum(m.shape[1] for m in test_matrices)
    
    test_processed = []
    for m in test_matrices:
        zero_mat = csr_matrix((m.shape[0], test_total_cols - m.shape[1]), dtype=m.dtype)
        test_processed.append(hstack([m, zero_mat]))
    
    result = vstack(test_processed)
    print(result.toarray())

# 运行测试
test_merge_example()

说明

  • 采用稀疏矩阵操作,补0过程不会占用额外内存,适合处理大规模文本数据
  • 保持所有矩阵的数据类型一致,避免拼接时出现类型错误
  • 最终矩阵的行数为所有输入矩阵行数之和,列数为所有输入矩阵列数之和,完全符合需求

内容的提问来源于stack exchange,提问作者CutePoison

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 19:24:57