Pandas 2.1.0 FutureWarning:不推荐Series.__getitem__将键视为位置

Pandas 2.1.0 FutureWarning: Series.__getitem__ treating keys as positions is deprecated

提问人:Zach Morris 提问时间:9/15/2023 更新时间:9/15/2023 访问量:5673

问:

我在使用 Pandas v2.1.0+ 时遇到了无法解决的问题。

我的 pandas 数据框中有一个列列表,我需要使用自定义函数进行转换。新值取决于数据中的多个列,因此我使用 apply 就地转换列:

my_columns_to_convert = ['col1','col2','col3']

for k in my_columns_to_convert:
  df[k] = df[[k,colx]].apply(lambda x: convert_my_data(value_1_in=x[0],value_2_in=x[1]),axis=1)

这在以前版本的 pandas 中运行良好。但现在我明白了:

FutureWarning: Series.__getitem__ treating keys as positions is deprecated. In a future version, integer keys will always be treated as labels (consistent with DataFrame behavior). To access a value by position, use `ser.iloc[pos]`

但我没有使用 loc 或 iloc,到目前为止我所审查的所有内容似乎都指向这就是问题所在。我怎样才能编写这段代码,以便将来以“正确”的方式编写它?

在 Pandas 中使用以前有效的方法。

Python pandas 警告

评论

0赞 Lfppfs 9/15/2023
你说“我没有使用 loc 或 iloc”,这正是警告告诉你要做的。也许使用 instead of 会摆脱警告(我不确定)。也许问题出在对象上。你能把它包含在你的帖子中吗?x.loc[0]x[0]colx
0赞 mozway 9/15/2023
请提供一个可重现的示例,其中包含输入数据集(作为代码)和虚拟函数的定义,不要忘记匹配的预期输出。convert_my_data
0赞 cottontail 12/20/2023
如果您在后端使用使用 pandas 的模块(例如 )收到此警告,除非您不想自己制作 PR,否则在开发人员更新源代码之前,您无能为力。好吧,我想你可以抑制警告;这个问答可能在这方面有所帮助。statsmodels.tsa

答:

6赞 Timeless 9/15/2023 #1

这可以在 2.1.0 中通过这个简单的示例触发:FutureWarning

ser = pd.Series({"A": "a", "B": "b", "C": "c"})

# A    a
# B    b
# C    c
# dtype: object

print(ser[1]) # gives 'b' but with a FutureWarning: Series.__getitem__ treating keys..

目标是在对 DataFrame 和 Series 进行 [ ] 索引时保持一致的行为。请记住,这不会返回位于该 DataFrame 的第二个位置的列,并且会触发 (除非文本 0 是实际列,在这种情况下,将返回该列) 。df[1]KeyError0


因此,根据您的代码,您的(请参阅下面的我如何想象)很可能没有默认索引(即 整数或至少一个整数列表)。因此,当在这里切片每个系列时,虽然索引是字符串,但熊猫会警告您使用 和 代替。dfx[0]x[1]["A", "B", "C"]x.iloc[0]x.iloc[1]

my_columns_to_convert = ['col1', 'col2', 'col3']

df = pd.DataFrame(
    np.arange(12).reshape(-1, 4),
    index=list("ABC"), columns= my_columns_to_convert + ["colx"]
)

#    col1  col2  col3  colx
# A     0     3     6     3
# B    28    35    42     7
# C    88    99   110    11

def convert_my_data(value_1_in, value_2_in):
    return value_1_in * value_2_in # a simple calculation

for k in my_columns_to_convert:
    df[k] = (
        df[[k, "colx"]].apply(
            lambda x: convert_my_data(value_1_in=x[0], value_2_in=x[1]), axis=1)
    )

# the FutureWarning is displayed three times (= the length of the Series) :

FutureWarning:不推荐将键视为位置。在将来的版本中,整数键将始终被视为标签(与 DataFrame 行为一致)。要按位置访问值,请使用:Series.__getitem__ser.iloc[pos]lambda x: convert_my_data(value_1_in=x[0], value_2_in=x[1]), axis=1)

顺便说一句,您的代码似乎效率不高,并且可能很容易矢量化。

3赞 Corralien 9/15/2023 #2

除了 @Timeless 的答案之外,您还可以通过扩展位置参数 () 来避免此警告:*x

for k in my_columns_to_convert:
    df[k] = (
        df[[k, "colx"]].apply(
            lambda x: convert_my_data(*x), axis=1)
    )

输出:

# before
>>> df
   col1  col2  col3  colx
A     0     1     2     3
B     4     5     6     7
C     8     9    10    11

# after
>>> df
   col1  col2  col3  colx
A     0     3     6     3
B    28    35    42     7
C    88    99   110    11