我有两个稀疏格式的数据帧,索引和列略有不同。我需要两个数据帧的串联数据帧的 coo 版本。当我尝试从它们生成 coo 矩阵时,我在
data
属性中得到零,这对我来说是意想不到的。即使所有列都有 pd.SparseDtype("float",0)
数据类型。看来 fillna(0) 方法引入了一些零,这些零渗透到稀疏格式的数据中......不应该包含零。
这里有一些代码来重现该行为
import pandas as pd
A = pd.DataFrame(np.eye(3),index=['a','b','c'],
columns=['a','b','c']).astype(pd.SparseDtype("float",0))
B = pd.DataFrame(np.random.normal(size=(2,2)),
index=['d','e'],
columns=['a','b'],
).astype(pd.SparseDtype("float",0))
c = pd.concat([A,B],axis=0).fillna(0)
在该示例中,
c.sparse.to_coo().data
或只是c.c.sparse.sp_values
都包含零,这违背了使用稀疏数据格式的目的。我不明白发生了什么事。如何以稀疏格式连接数据帧而不占用这些空间?我正在使用 pandas 版本 2.2.2
您的数据框和 coo 版本:
In [253]: A
Out[253]:
a b c
a 1.0 0.0 0.0
b 0.0 1.0 0.0
c 0.0 0.0 1.0
In [254]: print(A.sparse.to_coo())
(0, 0) 1.0
(1, 1) 1.0
(2, 2) 1.0
In [255]: B
Out[255]:
a b
d 1.300532 0.507797
e 2.716205 0.350493
In [256]: print(B.sparse.to_coo())
(0, 0) 1.3005317919570971
(1, 0) 2.716205281906014
(0, 1) 0.5077973046544041
(1, 1) 0.3504927594184647
以及串联版本:
In [257]: c
Out[257]:
a b c
a 1.000000 0.000000 0.0
b 0.000000 1.000000 0.0
c 0.000000 0.000000 1.0
d 1.300532 0.507797 0.0
e 2.716205 0.350493 0.0
In [258]: print(c.sparse.to_coo())
(0, 0) 1.0
(3, 0) 1.3005317919570971
(4, 0) 2.716205281906014
(1, 1) 1.0
(3, 1) 0.5077973046544041
(4, 1) 0.3504927594184647
(2, 2) 1.0
(3, 2) 0.0
(4, 2) 0.0
所以 (3,2) 和 (4,2) 来自
fillna
。如果您使用不同的填充,效果会更明显。
稀疏矩阵确实有一种删除多余零的方法。那不是自动的。而且我不太了解 pandas 稀疏代码,无法将其传递回数据框。
In [259]: M=c.sparse.to_coo()
In [260]: M.eliminate_zeros(); print(M)
(0, 0) 1.0
(3, 0) 1.3005317919570971
(4, 0) 2.716205281906014
(1, 1) 1.0
(3, 1) 0.5077973046544041
(4, 1) 0.3504927594184647
(2, 2) 1.0
In [261]: M.A
Out[261]:
array([[1. , 0. , 0. ],
[0. , 1. , 0. ],
[0. , 0. , 1. ],
[1.30053179, 0.5077973 , 0. ],
[2.71620528, 0.35049276, 0. ]])
使用其他 fillna 值:
In [262]: pd.concat([A,B],axis=0).fillna(np.nan)
Out[262]:
a b c
a 1.000000 0.000000 0.0
b 0.000000 1.000000 0.0
c 0.000000 0.000000 1.0
d 1.300532 0.507797 NaN
e 2.716205 0.350493 NaN
Pandas 稀疏代码在某种程度上是实验性的,因此像
concat
这样的步骤错过这样的细节也就不足为奇了。显然没有任何代码来检查 fillna
值是否与稀疏填充相同,并进行此类清理。