为什么一次使用iloc()会给出SettingWithCopyWarning,而另一次却没有呢? [英] Why does one use of iloc() give a SettingWithCopyWarning, but the other doesn't?

查看:158
本文介绍了为什么一次使用iloc()会给出SettingWithCopyWarning,而另一次却没有呢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在类的方法中,我使用以下语句:

Inside a method from a class i use this statement:

self.__datacontainer.iloc[-1]['c'] = value

这样做我得到
SettingWithCopyWarning:
A值试图在DataFrame的切片副本上设置

Doing this i get a "SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame"

现在我试图重现此错误并编写以下简单代码:

Now i tried to reproduce this error and write the following simple code:

import pandas, numpy
df = pandas.DataFrame(numpy.random.randn(5,3),columns=list('ABC'))
df.iloc[-1]['C'] = 3

那里我没有错误。为什么我在第一条语句而不是第二条语句中出现错误?

There i get no error. Why do i get an error in the first statement and not in the second?

推荐答案

链索引

作为文档以及此网站上的其他两个答案( [1] [2] )建议,

As the documentation and a couple of other answers on this site ([1], [2]) suggest, chain indexing is considered bad practice and should be avoided.

由于似乎没有一种使用基于整数位置的索引进行赋值的优雅方法, em>(即 .iloc ),而不会违反链式索引编制规则(从熊猫 v0.23.4 开始)建议尽可能使用基于标签的索引(即 .loc )进行分配。

Since there doesn't seem to be a graceful way of making assignments using integer position based indexing (i.e. .iloc) without violating the chain indexing rule (as of pandas v0.23.4), it is advised to instead use label based indexing (i.e. .loc) for assignment purposes whenever possible.

但是,如果您绝对需要按行号访问数据,则可以

However, if you absolutely need to access data by row number you can

df.iloc[-1, df.columns.get_loc('c')] = 42

df.iloc[[-1, 1], df.columns.get_indexer(['a', 'c'])] = 42






熊猫的行为很奇怪

据我了解,当您试图人为地复制错误时,期待警告是绝对正确的。

From my understanding you're absolutely right to expect the warning when trying to reproduce the error artificially.

到目前为止,我发现它取决于数据帧的构造方式

What I've found so far is that it depends on how a dataframe is constructed

df = pd.DataFrame({'a': [4, 5, 6], 'c': [3, 2, 1]})
df.iloc[-1]['c'] = 42 # no warning

df = pd.DataFrame({'a': ['x', 'y', 'z'], 'c': ['t', 'u', 'v']})
df.iloc[-1]['c'] = 'f' # no warning

df = pd.DataFrame({'a': ['x', 'y', 'z'], 'c': [3, 2, 1]})
df.iloc[-1]['c'] = 42 # SettingWithCopyWarning: ...

似乎熊猫(至少 v0.23.4 )在处理链分配时对混合类型和单一类型数据帧的处理方式不同> [3]

It seems that pandas (at least v0.23.4) handles mixed-type and single-type dataframes differently when it comes to chain assignments [3]


def _check_is_chained_assignment_possible(self):
    """
    Check if we are a view, have a cacher, and are of mixed type.
    If so, then force a setitem_copy check.
    Should be called just near setting a value
    Will return a boolean if it we are a view and are cached, but a
    single-dtype meaning that the cacher should be updated following
    setting.
    """
    if self._is_view and self._is_cached:
        ref = self._get_cacher()
        if ref is not None and ref._is_mixed_type:
            self._check_setitem_copy(stacklevel=4, t='referant',
                                     force=True)
        return True
    elif self._is_copy:
        self._check_setitem_copy(stacklevel=4, t='referant')
    return False


但是,有一个旧的错误

更新

根据开发人员上述行为是预期的。

According to the developers the above behaviour is expected.

这篇关于为什么一次使用iloc()会给出SettingWithCopyWarning,而另一次却没有呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆