如何修复 pandas 中的“试图在 DataFrame 的切片副本上设置值”警告?

问题描述 投票:0回答:2

我有以下 Python 函数:

def compute_average_fg_rating(df, mask=''):
    df = df[['HorseId', 'FGrating']]
    if len(mask) == 0:
        df.loc['cumsum'] = df.groupby('HorseId', group_keys=False)['FGrating'].apply(
            lambda x: x.shift(fill_value=0).cumsum())
        return df.loc['cumsum'] / df.groupby('HorseId')['FGrating'].cumcount()
    else:
        return df.loc[mask].groupby('HorseId', group_keys=False)['FGrating'].apply(
            lambda x: x.shift().expanding().mean())

当我尝试运行代码时,我在以下行收到“试图在 DataFrame 的切片副本上设置一个值”警告:

        df.loc['cumsum'] = df.groupby('HorseId', group_keys=False)['FGrating'].apply(
            lambda x: x.shift(fill_value=0).cumsum())

我看不到有问题的代码在哪里。你能帮帮我吗?

python pandas dataframe warnings
2个回答
1
投票

这是因为 df.loc['cumsum'] 不是对数据框中特定行的引用。在您的 if 语句中将其更改为:

cumsum_df = df.groupby('HorseId', group_keys=False)['FGrating'].apply(
            lambda x: x.shift(fill_value=0).cumsum())
df.loc[cumsum_df.index, 'cumsum'] = cumsum_df
        return df['cumsum'] / df.groupby('HorseId')['FGrating'].cumcount()

这应该可以解决您的问题


0
投票

警告消息表明操作

df.loc['cumsum'] = ...
正在尝试在原始 DataFrame df 的切片副本上设置值,而不是原始 DataFrame 本身。

当您使用索引或切片选择原始 DataFrame 的一个子集,然后就地修改该子集时,可能会发生这种情况。在某些情况下,pandas 返回子集的副本而不是原始 DataFrame 的视图,并且尝试修改此副本可能会导致意外行为。

在这种情况下,问题在于行

df = df[['HorseId', 'FGrating']]
,它通过仅选择列“HorseId”和“FGrating”来创建一个新的 DataFrame,它是原始 df 的子集。这将创建子集的副本,而不是原始 DataFrame 的视图。

要修复警告消息,您可以修改代码以避免创建 DataFrame 的副本。一种方法是使用

loc
访问器在同一操作中选择行和列:

df = df.loc[:, ['HorseId', 'FGrating']]

这将选择所有行 (:) 和列“HorseId”和“FGrating”。通过使用 loc 访问器,您可以确保选择返回原始 DataFrame 的视图,而不是副本。

通过此更改,修改后的功能将是:

def compute_average_fg_rating(df, mask=''):
    df = df.loc[:, ['HorseId', 'FGrating']]
    if len(mask) == 0:
        df.loc['cumsum'] = df.groupby('HorseId', group_keys=False)['FGrating'].apply(
            lambda x: x.shift(fill_value=0).cumsum())
        return df.loc['cumsum'] / df.groupby('HorseId')['FGrating'].cumcount()
    else:
        return df.loc[mask].groupby('HorseId', group_keys=False)['FGrating'].apply(
            lambda x: x.shift().expanding().mean())

这应该可以解决警告消息。

© www.soinside.com 2019 - 2024. All rights reserved.