【问题标题】:Select part of Dataframe to obtain a view, not a copy选择部分 Dataframe 以获取视图,而不是副本
【发布时间】:2019-11-10 13:15:41
【问题描述】:

如何选择原始变量“frame”的一部分,使得改变“frame2”也会改变“frame”?以下不起作用。

import pandas as pd
frame = pd.DataFrame([[1,2,3],[1,5,6], [7,8,9]])
frame2 = frame.loc[frame.loc[:,0] == 1]
frame2.loc[:,1] = -99

谢谢!

【问题讨论】:

  • 你需要添加 .copy()
  • 如果没有 WeNYoBen 推荐的 .copy(),frame 和 frame2 都指向内存中的同一个对象。当您使用 .copy() 时,您正在创建帧变量引用的数据帧的副本。frame2 = frame.loc[frame.loc[:,0] == 1].copy() 是您要查找的内容。
  • 我认为他们想要同时修改两者,顺便说一句,这是一种糟糕的做法。 API 的设计方式无法做到这一点。

标签: python pandas


【解决方案1】:

重要的一点是loc(以及扩展名ilocatiat)将始终返回一个副本。

如果你想要一个视图,你必须通过__getitem__ 索引frame。现在,即使这样也不能保证返回视图或副本——这是一个实现细节,不容易分辨。

在以下索引操作之间,

frame2 = frame[frame.iloc[:,0] == 1]
frame3 = frame[frame > 0]
frame4 = frame2[[0, 1]]

frame2._is_view
# False
frame3._is_view
# True
frame4._is_view
# False

只有frame3 将是一个视图。细节还取决于 dtypes 和其他因素(例如切片的形状),但这是一个明显的区别。

尽管frame3 是一个视图,对它的修改可能会起作用或不起作用,但它们永远不会导致对frame 的更改。开发人员已经进行了大量检查 (most notably the SettingWithCopyWarning) 以防止修改视图产生意外的副作用。

frame3.iloc[:, 1] = 12345
frame3
   0      1  2
0  1  12345  3
1  1  12345  6
2  7  12345  9

frame
   0  1  2
0  1  2  3
1  1  5  6
2  7  8  9

TLDR;请寻找一种不同的方式来做你想做的任何事情。

【讨论】:

  • 不知道_is_view。 +1
  • @harvpan 我通常避免接触隐藏或私人属性,特别是因为它们并不总是准确的,并且可能会更改或完全删除,但在这种情况下是 common method 来检查视图。
猜你喜欢
  • 2017-03-24
  • 2013-01-23
  • 1970-01-01
  • 1970-01-01
  • 2021-03-12
  • 2014-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多