• pandas警告:SettingWithCopyWarning


      在使用pandas对DataFrame进行赋值操作时,会出现一个看似莫名巧妙的告警信息:

      SettingWithCopyWarning:A value is trying to be set on a copy of slice from a DataFrame

      Try using .loc[row_indexer,col_indexer] = value instead

      这条告警信息的大意是,“尝试在DataFrame一个切片的副本上进行赋值,使用 .loc[row_indexer,col_indexer] = value 代替当前赋值操作”。导致这条告警产生的原因,是由于pandas无法判断对原始DataFrame进行切片,产生的是视图还是副本。如果切片产生的是视图,则赋值操作会修改原始DataFrame,如果产生的是副本,则不会修改原始的DataFrame。

      一般产生这条告警,都是由于使用链式索引(chained indexing)赋值导致的;而使用  .loc[row_indexer,col_indexer] 则会产生一个新的DataFrame,在某些情况下,可以解决该告警问题(ps:导致 SettingWithCopyWarning 告警产生的情况不止一种!)。如果你选择忽视这条告警,那么你最好查看一下自己的赋值操作有没有成功(虽然本人实际运用中查看了多次,都是成功的,但不代表每一次都能成功,所以建议还是不要忽视这条告警)。

    # 下面的操作就会出现SettingWithCopyWarning警告
    df_select = df[df['col_name]>value]   # 通过条件筛选,得到df_select
    # 假设此时我们想修改df_select列 'col'的值:
    df_select['col']  = new_value
    # 此时就会出现SettingWithCopyWarning,因为df_select 发生改变,pandas无法判断原始df究竟会不会改变
    # 实际上上述过程就用了链式索引进行赋值,上述过程等价于:
     df[df['col_name]>value]['col']  = new_value
    # 解决这个问题比较好的一个方法是手动进行复制:
    df_select = df[df['col_name]>value].copy()  # 这样df_select是df的一个复本,df_select的改变也不会影响df

      

      总而言之,应该竟可能的避免使用链式索引对 DataFrame 进行赋值操作。更多产生告警的原因及解决方法的详解,可以参考pandas官方文档中的 "Indexing and Selecting Data"模块下的"Returning a view versus a copy"  http://pandas.pydata.org/pandas-docs/stable/indexing.html#returning-a-view-versus-a-copy。也可参考我看到一篇写的很好的文章:https://www.dataquest.io/blog/settingwithcopywarning/(英文原文),https://www.jianshu.com/p/72274ccb647a(中文翻译版)。

  • 相关阅读:
    JAVA 设计模式 状态模式
    JAVA 设计模式 访问者模式
    JAVA 设计模式 策略模式
    python获取本机IP地址
    如何在python的字符串中输入纯粹的{}
    在终端打印有颜色的文本
    vim文本替换命令
    selenium WebDriverException: Message: unknown error: DevToolsActivePort file doesnt exist
    history显示历史操作记录,并显示操作时间
    linux下chrome和chromedriver的安装
  • 原文地址:https://www.cnblogs.com/solong1989/p/9830471.html
Copyright © 2020-2023  润新知