使用 .loc[] 直接在稀疏格式中插入数据是很令人沮丧的,我只能提供一种解决方法。
自问题发布以来(版本 0.25),pandas 已经弃用了 SparseDataFrame,并创建了一种数据类型(SparseDtype),可以将其应用于 DataFrame 内的单个序列。换句话说,它不再是 "全有或全无" 的形式。你可以:
- 将 DataFrame 中的几列转换为 dense 格式,同时保持其他列为 sparse 格式,
- 在 dense 列中使用 .loc[] 插入数据,
- 然后再将这些列转换为 sparse 格式。
这显然比将整个 DataFrame 转换为 dense 格式要节省很多内存。
下面是一个非常简单的函数,以说明我的意思:
def sp_loc(df, index, columns, val):
""" Insert data in a DataFrame with SparseDtype format
Only applicable for pandas version > 0.25
Args
----
df : DataFrame with series formatted with pd.SparseDtype
index: str, or list, or slice object
Same as one would use as first argument of .loc[]
columns: str, list, or slice
Same one would normally use as second argument of .loc[]
val: insert values
Returns
-------
df: DataFrame
Modified DataFrame
"""
spdtypes = df.dtypes[columns]
df[columns] = df[columns].sparse.to_dense()
df.loc[index, columns] = val
df[columns] = df[columns].astype(spdtypes)
return df
简单示例:
df1 = pd.DataFrame(index=['a', 'b', 'c'], columns=['I', 'J'])
df1.loc['a', 'J'] = 0.42
df1 = df1.astype(pd.SparseDtype(float))
df1.dtypes
df1.sparse.density
df1 = sp_loc(df1, ['a','b'], 'I', [-1, 1])
df1.sparse.density()