稀疏数据结构#

pandas 提供了用于高效存储稀疏数据的数据结构。这些不一定是典型的“大部分为 0”的稀疏。更准确地说,你可以将这些对象视为“压缩”的,其中任何与特定值(NaN / 缺失值,尽管任何值都可以选择,包括 0)匹配的数据都被省略了。压缩后的值实际上并未存储在数组中。

注意 dtype,Sparse[float64, nan]nan 表示数组中是 nan 的元素实际上并未存储,只有非 nan 元素才存储。这些非 nan 元素的 dtype 是 float64

稀疏对象存在是为了提高内存效率。假设你有一个大型的、大部分是 NA 的 DataFrame

正如你所见,密度(未“压缩”的值的比例)非常低。这个稀疏对象在磁盘(pickle 后)和 Python 解释器中占用的内存要少得多。

功能上,它们的行为应该与其密集对应物几乎相同。

SparseArray#

arrays.SparseArray 是一个 ExtensionArray ,用于存储稀疏值的数组(有关扩展数组的更多信息,请参阅 dtypes )。它是一个一维的 ndarray 类对象,仅存储与 fill_value 不同的值:

可以使用 numpy.asarray() 将稀疏数组转换为常规(密集)ndarray

SparseDtype#

SparseArray.dtype 属性存储两个信息

  1. 非稀疏值的 dtype

  2. 标量填充值

可以通过仅传递 dtype 来构造 SparseDtype

在这种情况下,将使用默认填充值(对于 NumPy dtypes,这通常是该 dtype 的“缺失”值)。要覆盖此默认值,可以传递一个显式的填充值

最后,字符串别名 'Sparse[dtype]' 可用于在许多地方指定稀疏 dtype

稀疏访问器#

pandas 提供了一个 .sparse 访问器,类似于字符串数据的 .str、分类数据的 .cat 和 datetime 类型数据的 .dt。这个命名空间提供了特定于稀疏数据的属性和方法。

此访问器仅在具有 SparseDtype 的数据上可用,并且在 Series 类本身上可用,用于使用 scipy COO 矩阵创建具有稀疏数据的 Series。

还为 DataFrame 添加了 .sparse 访问器。有关更多信息,请参阅 稀疏访问器 (Sparse accessor)

稀疏计算#

你可以将 NumPy 的 ufuncs 应用于 arrays.SparseArray ,并得到 arrays.SparseArray 作为结果。

ufunc 也会应用于 fill_value。这是获得正确密集结果所必需的。

转换

要将数据从稀疏转换为密集,请使用 .sparse 访问器

从密集到稀疏,使用 DataFrame.astype()SparseDtype

scipy.sparse 的交互#

使用 DataFrame.sparse.from_spmatrix() 从稀疏矩阵创建具有稀疏值的 DataFrame

支持所有稀疏格式,但非 COOrdinate 格式的矩阵将被转换,根据需要复制数据。要转换回 COO 格式的稀疏 SciPy 矩阵,可以使用 DataFrame.sparse.to_coo() 方法:

实现 Series.sparse.to_coo() 是为了将由 Series 索引的、具有稀疏值的 MultiIndex 转换为 scipy.sparse.coo_matrix

该方法需要一个 MultiIndex ,其中包含两个或更多级别。

在下面的示例中,我们通过指定第一个和第二个 MultiIndex 级别定义行的标签,以及第三个和第四个级别定义列的标签,将 Series 转换为二维数组的稀疏表示。我们还指定最终稀疏表示中的列和行标签应进行排序。

指定不同的行和列标签(并且不排序它们)会产生不同的稀疏矩阵:

实现了一个方便的方法 Series.sparse.from_coo() ,用于从 scipy.sparse.coo_matrix 创建具有稀疏值的 Series

默认行为(使用 dense_index=False)仅返回一个包含非空项的 Series

指定 dense_index=True 将导致索引成为矩阵的行和列坐标的笛卡尔积。请注意,如果稀疏矩阵足够大(并且稀疏),这将消耗大量的内存(相对于 dense_index=False)。