从数组设置整个列时如何摆脱就地 FutureWarning?

回答 4 浏览 4822 2022-10-13

在pandas v.1.5.0 添加了一个新警告,当从不同数据类型的数组设置列时显示。 FutureWarning 通知计划中的语义更改,当使用 iloc 时:the change will be done in-place in future versions。 changelog 指示如何获得旧行为,但没有提示如何处理这种情况,而就地操作实际上是正确的选择。

变更日志中的例子:

df = pd.DataFrame({'price': [11.1, 12.2]}, index=['book1', 'book2'])
original_prices = df['price']
new_prices = np.array([98, 99])
df.iloc[:, 0] = new_prices
df.iloc[:, 0]

这是在 pandas 1.5.0 中打印的警告:

FutureWarning: In a future version, df.iloc[:, i] = newvals will attempt to set the values inplace instead of always setting a new array. To retain the old behavior, use either df[df.columns[i]] = newvals or, if columns are non-unique, df.isetitem(i, newvals)

如果我不关心就地与否,但想摆脱警告,如何摆脱警告?我应该显式更改 dtype 吗?我真的需要在每次需要使用此功能时都收到警告吗?难道没有更好的办法吗?

lumbric 提问于2022-10-13
为什么不把df.iloc[:, 0] = new_prices换成df[df.columns[0]] = new_prices,就像警告信息所建议的那样呢?Laurent 2022-10-15
@Laurent 因为没有理由让我保留旧的行为。lumbric 2022-10-17
该警告令人困惑,因为该变化同时适用于loc和iloc - pandas.pydata.org/docs/whatsnew/…JuanPi 2022-10-18
你可以使用warnings模块制作一个正则表达式来忽略警告。例如,warnings.filterwarnings('ignore', '[\s\w\W]*non-unique[\s\w\W]*', FutureWarning)Oluwafemi Sule 2022-10-26
@OluwafemiSule 请看我自己在下面的回答,这基本上就是我所做的事情。lumbric 2022-10-31
4 个回答
#1楼 已采纳
得票数 9

除了使用warnings模块抑制警告外,我还没有找到更好的方法:

import numpy as np
import pandas as pd
import warnings

df = pd.DataFrame({"price": [11.1, 12.2]}, index=["book1", "book2"])
original_prices = df["price"]
new_prices = np.array([98, 99])
with warnings.catch_warnings():
    # Setting values in-place is fine, ignore the warning in Pandas >= 1.5.0
    # This can be removed, if Pandas 1.5.0 does not need to be supported any longer.
    # See also: https://stackoverflow.com/q/74057367/859591
    warnings.filterwarnings(
        "ignore",
        category=FutureWarning,
        message=(
            ".*will attempt to set the values inplace instead of always setting a new array. "
            "To retain the old behavior, use either.*"
        ),
    )

    df.iloc[:, 0] = new_prices

df.iloc[:, 0]
lumbric 提问于2022-10-25
#2楼
得票数 4

正如更新日志所述,当从一个数组中设置整个列时,警告会被打印出来,具有不同的dtype,所以调整dtype是消除它的一个方法。

df = pd.DataFrame({'price': [11.1, 12.2]}, index=['book1', 'book2'])
original_prices = df['price']
new_prices = np.array([98, 99]).astype(float)
df.iloc[:, 0] = new_prices
df.iloc[:, 0]

注意额外的.astype(float)。这不是一个理想的解决方案,但却是一个解决方案。

Alperino 提问于2022-12-02
为什么不直接使用[98.0, 99.0]而不是[98, 99]?那么你就不需要.astype(float)了。John 2023-02-24
因为.astype(float)的方法是你在现实生活中会做的事情,[98, 99]被替换成一个有未知项的数组xAlperino 2023-02-24
#3楼
得票数 0

在这里发帖,因为我还不能发表评论。

现在我想我也会抑制这些警告,因为我不想要旧的行为,从来没有想到会以这种方式使用它。而且建议的语法有触发SettingWithCopyWarning警告的危险。

Dong Wang 提问于2022-11-01
#4楼
得票数 -2

我只是暂时过滤了所有未来的警告。

import warnings
warnings.simplefilter("ignore", category=FutureWarning)
Rafael de Rezende 提问于2022-10-28
Nikita Shabankin 修改于2022-10-28
我不认为这是一种好的做法,尤其是在导入其他地方的代码中。警告的存在是有原因的,所以不检查就把所有的警告消音可能是危险的。lumbric 2022-10-31
标签