在 Pandas 中给 SparseArray 赋值?

9

我有一个 SparseDataFrame 类型的对象,我想要更改一些值。

通常情况下,当我使用dataframes时,我会使用 DataFrame.locDataFrame.ilocset_value。但是在尝试在 SparseDataFrame 对象上使用这些方法时,我总是会得到以下错误:

"SparseArray does not support item assignment via setitem"
TypeError: SparseArray does not support item assignment via setitem

如何正确使用SparseArray?

这个问题:Set percentage of column to 0 (pandas)建议首先使用df.to_dense(),进行赋值后再使用df.to_sparse()将其转换回来。我想知道是否有一种直接使用SparseDataFrame / SparseArray的方法?

1个回答

3

使用 .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

    """

    # Save the original sparse format for reuse later
    spdtypes = df.dtypes[columns]

    # Convert concerned Series to dense format
    df[columns] = df[columns].sparse.to_dense()

    # Do a normal insertion with .loc[]
    df.loc[index, columns] = val

    # Back to the original sparse format
    df[columns] = df[columns].astype(spdtypes)

    return df

简单示例:

# DÉFINITION DATAFRAME SPARSE

df1 = pd.DataFrame(index=['a', 'b', 'c'], columns=['I', 'J'])
df1.loc['a', 'J'] = 0.42
df1 = df1.astype(pd.SparseDtype(float))
#     |   I |      J
# ----+-----+--------
# a   | nan |   0.42
# b   | nan | nan
# c   | nan | nan

df1.dtypes
#I    Sparse[float64, nan]
#J    Sparse[float64, nan]

df1.sparse.density
# 0.16666666666666666

# INSERTION

df1 = sp_loc(df1, ['a','b'], 'I', [-1, 1])
#     |   I |      J
# ----+-----+--------
#  a  |  -1 |   0.42
#  b  |   1 | nan
#  c  | nan | nan

df1.sparse.density()
# 0.5

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接