当前位置: 首页 > 面试题库 >

困惑关于:pandas复制的数据帧警告

薛淳
2023-03-14
问题内容

我浏览了与该问题相关的一堆问题和答案,但是我仍然发现我在意想不到的地方得到了切片警告的副本。另外,它的代码在以前对我来说运行良好,这使我想知道某种更新是否可能是罪魁祸首。

例如,这是一组代码,其中我要做的就是将Excel文件读入pandas中DataFrame,并减少df[[]]语法中包含的列集。

 izmir = pd.read_excel(filepath)
 izmir_lim = izmir[['Gender','Age','MC_OLD_M>=60','MC_OLD_F>=60','MC_OLD_M>18','MC_OLD_F>18','MC_OLD_18>M>5','MC_OLD_18>F>5',
               'MC_OLD_M_Child<5','MC_OLD_F_Child<5','MC_OLD_M>0<=1','MC_OLD_F>0<=1','Date to Delivery','Date to insert','Date of Entery']]

现在,我对该izmir_lim文件所做的任何进一步更改都会引发切片警告的副本。

izmir_lim['Age'] = izmir_lim.Age.fillna(0)
izmir_lim['Age'] = izmir_lim.Age.astype(int)

/Users/samlilienfeld/anaconda/lib/python3.5/site-packages/ipykernel/
main .py:2:SettingWithCopyWarning:试图在DataFrame的切片副本上设置一个值。尝试改用.loc
[row_indexer,col_indexer] = value

我很困惑,因为我认为df[[]]默认情况下列设置返回了一个副本。我发现抑制错误的唯一方法是显式添加df[[]].copy()。我本可以发誓过去我不必这样做,也不会提出切片错误的副本。

同样,我还有一些其他代码,可在数据帧上运行函数以某些方式对其进行过滤:

def lim(df):
if (geography == "All"):
    df_geo = df
else:
    df_geo = df[df.center_JO == geography]

df_date = df_geo[(df_geo.date_survey >= start_date) & (df_geo.date_survey <= end_date)]

return df_date

df_lim = lim(df)

从现在开始,我对任何值的任何更改都会df_lim提高切片错误的副本。我发现围绕它的唯一方法是将函数调用更改为:

df_lim = lim(df).copy()

这对我来说似乎是错误的。我想念什么?看来这些用例默认情况下应该返回副本,而且我可能发誓,上次运行这些脚本时,我并没有遇到这些错误。
我是否只需要开始添加.copy()整个地方?似乎应该有一种更清洁的方法来执行此操作。任何见解或帮助,我们将不胜感激。


问题答案:

izmir = pd.read_excel(filepath)
izmir_lim = izmir[[‘Gender’,’Age’,’MC_OLD_M>=60’,’MC_OLD_F>=60’,
‘MC_OLD_M>18’,’MC_OLD_F>18’,’MC_OLD_18>M>5’,
‘MC_OLD_18>F>5’,’MC_OLD_M_Child<5’,’MC_OLD_F_Child<5’,
‘MC_OLD_M>0<=1’,’MC_OLD_F>0<=1’,’Date to Delivery’,
‘Date to insert’,’Date of Entery’]]

izmir_lim是的视图/副本izmir。随后,您尝试分配给它。这就是引发错误的原因。使用此代替:

 izmir_lim = izmir[['Gender','Age','MC_OLD_M>=60','MC_OLD_F>=60',
                    'MC_OLD_M>18','MC_OLD_F>18','MC_OLD_18>M>5',
                    'MC_OLD_18>F>5','MC_OLD_M_Child<5','MC_OLD_F_Child<5',
                    'MC_OLD_M>0<=1','MC_OLD_F>0<=1','Date to Delivery',
                    'Date to insert','Date of Entery']].copy()

每当您以下列方式从另一个“创建”新数据框时:

new_df = old_df[list_of_columns_names]

new_df它的is_copy属性将具有真实值。当您尝试分配给它时,熊猫会抛出SettingWithCopyWarning

new_df.iloc[0, 0] = 1  # Should throw an error

您可以通过多种方式克服这一点。

选项1

new_df = old_df[list_of_columns_names].copy()

选项2(如@ayhan在评论中建议)

new_df = old_df[list_of_columns_names]
new_df.is_copy = None

选项#3

new_df = old_df.loc[:, list_of_columns_names]


 类似资料:
  • 当您可以调用递归方法而不是必须将递归方法设置为变量时,是否有一种简单的方法来理解? 例如... 只是调用递归函数遍历: self.recurse(node.left) self.recurse(node.right) 必须将递归函数设置为node。左和右。右: 节点。左=自我。递归(node.left) 节点。右=自我。递归(node.left) 另一个例子是删除bst中的一个节点,你必须将递归函

  • 1.首先,我想确认一下从编程的角度,我们有“静态类型检查”和“动态类型检查,对把? 2.一般情况下我们用typescript做静态类型检查,检查源码里面自定义数据类型,对把? 3.那么,我们做的所谓的动态类型检查是不是指的那些库,比如Joi,ajv什么的,比如你点击一个按钮,然后调这个库来检查一个obj的schema,如果类面的key value类型都能对的上,我们就通过,如果类型对不上,我们就报

  • 问题内容: 在Node.js Express模块​​的代码中,我碰到了这一行,为服务器设置继承: 我不确定这样做是什么- MDC文档(https://developer.mozilla.org/en/JavaScript/Guide/Inheritance_Revisited#prototype_and_ proto )似乎说我可以这样做: 确实,我做了这个测试: 看起来一样吗?所以,是的,我想知

  • 例如,一个方法中有10000次循环。当它运行1000次时,backedge\u计数器触发JIT编译。解释器继续执行。当它循环4000次时,JIT编译完成。 我的问题是,剩余的6000次是如何由解释器执行的,还是如何执行本机代码?或者在下次调用此方法之前不会执行本机代码?下次调用此方法时会发生什么?

  • 但后者给了我下面的例外。这是为什么? java.lang.StringIndexOutOfBoundsException:String index超出范围:1 java.lang.StringIndexOutOfBoundsException:String index超出范围:1 java.lang.String.charat(String.java:658)在Scala.Collection.i

  • 我无法理解这句话(特别是粗体部分): 类型“指向 cv1 void 的指针”的 prvalue 可以转换为类型为“指向 cv2 T”的 prvalue,其中 T 是对象类型,cv2 是与 cv1 相同的 cv 限定或大于 cv1 的 cv 限定。如果原始指针值表示内存中某个字节的地址 A,并且 A 不满足 T 的对齐要求,则生成的指针值未指定。 我的问题是: > (的地址)指向的地址是否满足 的对