我有一个数据框说 release_dates
release_dates
我使用某些条件进行了过滤,并将其命名为 b
b = release_dates[(release_dates.title.str.startswith('The Hobbit')) &
(release_dates.country =='USA')]
现在我希望通过从日期列中提取月份来显示其他列。 我使用下面的命令工作正常,但引发了错误
b['month'] = b['date'].dt.month #code1
C:\Users\user110244\Anaconda3\lib\site-packages\pandas\core\indexing.py:288: SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead
我按照代码的建议阅读documentation,根据我的理解,我知道我应该使用以下命令(在链式索引的情况下),因为使用上面的命令使得很难预测它是否会返回一个视图或一个副本(它取决于数组的内存布局,关于哪些pandas不能保证)和code2比code1更有效文档。
b.loc[:,'month']=b.loc[:,'date'].dt.month #code2
但是使用它也会引发同样的错误。
有人可以解释为什么会发生这种情况吗?我如何确保我的代码在两种情况下都是正确的' a'和' b'? 如何关闭此警告?
我想指出的另一件事是,我使用了具有不同条件的相同代码,并没有得到任何错误
a =release_dates[(release_dates.title.str.contains('Christmas'))&
(release_dates.country =='USA')].sort_values('year')
a['month'] = a['date'].dt.month
a.head()
答案 0 :(得分:2)
正如Edchum在评论中清楚地解释说你在第一个代码中使用 .sort()让python知道用户知道,它是一个副本而不是一个视图。
每当我们执行切片或过滤时,我们会获得一个视图或一个副本。但是,Pandas文档没有指定任何关于视图或副本的预期规则。
让我尝试扩展一下。 避免此类警告的一种简单方法是使用 .copy()
b = (release_dates.title.str.startswith('The Hobbit')) &
(release_dates.country =='USA')
b1 = b.copy()
b1['month'] = b1['date'].dt.month #code1
通过执行此操作,您明确告诉Python您正在处理的内容,即在视图或副本上,Python不会显示警告。
但请记住,每次制作副本会占用大量内存。所以在必要时这样做。
您还可以使用
检查两个对象是否指向同一个内存np.may_share_memory(b,b1)
False
为特定对象关闭警告的另一种方法是使用 .is_copy()= False 在这种情况下,我们可以使用
b.is_copy()= False