Python 使用稀疏列对pandas.DataFrame中的行进行基于索引的访问
由于内存限制,我不得不在Python 使用稀疏列对pandas.DataFrame中的行进行基于索引的访问,python,pandas,dataframe,sparse-matrix,Python,Pandas,Dataframe,Sparse Matrix,由于内存限制,我不得不在pandas.DataFrame(pandas版本1.0.5)中使用稀疏列。 不幸的是,对于基于索引的行访问(使用.loc[]),我遇到了以下问题: df = pd.DataFrame.sparse.from_spmatrix( scipy.sparse.csr_matrix([[0, 0, 0, 1], [1, 0, 0, 0], [0, 1, 0
pandas.DataFrame
(pandas版本1.0.5)中使用稀疏列。
不幸的是,对于基于索引的行访问(使用.loc[]
),我遇到了以下问题:
df = pd.DataFrame.sparse.from_spmatrix(
scipy.sparse.csr_matrix([[0, 0, 0, 1],
[1, 0, 0, 0],
[0, 1, 0, 0]])
)
输出:
0 1 2 3
0 0 0 0 1
1 1 0 0 0
2 0 1 0 0
0 1 2 3
0 0 0 NaN 1
1 1 0 NaN 0
0 Sparse[int32, 0]
1 Sparse[int32, 0]
2 Sparse[float64, 0]
3 Sparse[int32, 0]
0 1 2 3
0 0 0 0 1
1 1 0 0 0
如果使用.loc
:
df.loc[[0,1]]
输出:
0 1 2 3
0 0 0 0 1
1 1 0 0 0
2 0 1 0 0
0 1 2 3
0 0 0 NaN 1
1 1 0 NaN 0
0 Sparse[int32, 0]
1 Sparse[int32, 0]
2 Sparse[float64, 0]
3 Sparse[int32, 0]
0 1 2 3
0 0 0 0 1
1 1 0 0 0
理想情况下,我希望第二列也有0
s。我对这里发生的事情的假设是,内部csc矩阵表示和我访问不包含任何非零值的列的行中的值这一事实最初会与填充值相混淆。d类型
有点反对这一点:
df.loc[[0,1]].dtypes
输出:
0 1 2 3
0 0 0 0 1
1 1 0 0 0
2 0 1 0 0
0 1 2 3
0 0 0 NaN 1
1 1 0 NaN 0
0 Sparse[int32, 0]
1 Sparse[int32, 0]
2 Sparse[float64, 0]
3 Sparse[int32, 0]
0 1 2 3
0 0 0 0 1
1 1 0 0 0
(请注意,即使第2列的视图的dtype
已从Sparse[int32,0]
更改为Sparse[float64,0]
,填充值仍为0
)
有谁能告诉我,在一行切片的
pd.DataFrame
中出现的具有稀疏列的所有NaN
是否确实引用了相应的零值,并且不会“隐藏”任何实际的非零条目?是否有一种“安全”的方法可以在稀疏列的pd.DataFrame
s上使用基于索引的行访问?因此这确实是pandas
中的一个错误,该错误已在1.1.0版中修复(有关问题描述和解决方案,请参阅)
在1.1.0中,最简单的示例是:
df = pd.DataFrame.sparse.from_spmatrix(
scipy.sparse.csr_matrix([[0, 0, 0, 1],
[1, 0, 0, 0],
[0, 1, 0, 0]])
)
df.loc[[0, 1]]
输出:
0 1 2 3
0 0 0 0 1
1 1 0 0 0
2 0 1 0 0
0 1 2 3
0 0 0 NaN 1
1 1 0 NaN 0
0 Sparse[int32, 0]
1 Sparse[int32, 0]
2 Sparse[float64, 0]
3 Sparse[int32, 0]
0 1 2 3
0 0 0 0 1
1 1 0 0 0
有趣的
df.loc[0:1]
试试这个。是的,就是这样(尽管我的用例需要具体的索引值)。我从来没有研究过.loc
实现的细节,但一个切片可以工作,而一个具体的索引(上面的问题也发生在pd.index([0,1])
中)却不能工作,这似乎有点奇怪。你可能知道为什么会出现这种情况吗?不确定,但我猜测,.loc[[0,1]]
正在访问每个索引并返回一个串联(因此在列2中没有数据),而.loc[0:1]
或通常的.loc[0:1,:]
似乎在构建索引和列切片,然后查找数据(因此,将所有IDX/COL放入切片中并重建稀疏矩阵)…解决方法是df.loc[[0,1]]].fillna().astype(np.int32)
,您是否研究过更小的数据类型?比如np.int8
或np.bool