Scipy 稀疏矩阵作为 DataFrame 列

Posted

技术标签:

【中文标题】Scipy 稀疏矩阵作为 DataFrame 列【英文标题】:Scipy sparse matrix as DataFrame column 【发布时间】:2017-01-19 11:00:01 【问题描述】:

我正在开发基于 pandas DataFrame 对象的工具。我想将 scipy 稀疏矩阵保留为 DataFrame 的列,而不是将其逐行转换为 dtype('O') 的列表/numpy 数组。

下面的 sn-p 不起作用,因为 pandas 将矩阵视为标量,并建议添加索引。在矩阵中的行索引上提供 pd.RangeIndex 时,矩阵会针对数据帧中的每一行重复(因为 pandas 认为它​​是一个标量)。

ma = scipy.sparse.rand(10, 100, 0.1, 'csr', dtype=np.float64)
df = pd.DataFrame(dict(X=ma))

这确实有效:

df = pd.DataFrame(dict(X=list(ma)))

但是,这会将矩阵逐行分割为 CSR 矩阵,每行 1 行。每次我想处理原始矩阵时,我都需要 vstack。

有什么建议吗?我尝试将 CSR 矩阵包装到 pd.Series 对象中,假装它具有 dtype('O'),但我遇到了很多关于底层数据是 numpy 数组等的假设。

【问题讨论】:

【参考方案1】:

存在稀疏数据框或数据序列功能。它仍然是实验性的。我已经回答了一些关于在它和scipy 稀疏矩阵之间来回转换的问题。

从侧边栏:

Populate a Pandas SparseDataFrame from a SciPy Sparse Coo Matrix

如果没有这种专门的 pandas 结构,我看不到如何将稀疏矩阵添加到 pandas 框架中。稀疏矩阵的内部结构差异太大。首先,它不是 numpy 数组的子类。

csr 矩阵是一个对象,其数据包含在 3 个数组中,ma.datama.indices 是一维数组,数组的每个非零元素都有一个值。 ma.indptr 对矩阵的每一行都有一个值。

list(ma) 毫无意义。 ma.toarray() 生成一个包含相同数据的二维数组,并且所有这些零也会被填充。

其他稀疏矩阵格式将它们的数据存储在其他结构中 - coo 有 3 个等长数组,lil 有两个列表列表,dok 有一个字典。

【讨论】:

感谢@hpaulj 的回复。我实际上对通过 Pandas 逐列访问 SciPy 矩阵不感兴趣,只对逐行或整个矩阵进行访问。我了解内存布局级别上 ndarray 和稀疏矩阵类型之间的不匹配。我希望有一个抽象,两者都可以适应...list(ma) 并非毫无意义,至少对于 CSR 矩阵,它为原始 CSR 矩阵中的每一行创建一行的 CSR 矩阵。 我看不出如何将密集或稀疏的矩阵 (2d) 用作 Dataframe 的列。我相信pandas 会尝试将二维数组的列映射到相同数量的列上。单元格也可以是对象指针,但不能是整列。但我对 numpy 和 scipy 的了解胜过 pandas。 再次感谢。我明白。将是存储特征向量的 CSR 矩阵的方便位置,其中非常行对应于例如DataFrame 的另一列中的标签,并且能够访问底层 CSR 矩阵 将其复制或堆叠在一起。不能拥有我猜的一切:)【参考方案2】:

诚然,这并不能准确回答您的问题,但如果有人正在寻找一种快速的解决方法,并且不介意将矩阵存储为密集的低效,则可以这样做:

df = pd.DataFrame(X=ma.todense().tolist())

【讨论】:

以上是关于Scipy 稀疏矩阵作为 DataFrame 列的主要内容,如果未能解决你的问题,请参考以下文章

Scipy---6.稀疏矩阵

计算 scipy 稀疏矩阵的稀疏传递闭包

python中scipy学习——随机稀疏矩阵及操作

优化 Scipy 稀疏矩阵

Scipy稀疏矩阵维度问题

将稀疏 scipy 矩阵加载到现有的 numpy 密集矩阵中