TL;DR:
如果返回副本(然后更改值不会改变DataFrame)或values返回视图(然后更改值会更改 DataFrame)。不要依赖任何这些情况。如果 pandas 开发人员认为它是有益的,它可能会改变(例如,如果他们改变了 DataFrame 的内部结构)。
我猜自提出问题以来文档已更改,目前显示为:
pandas.DataFrame.values
返回 DataFrame 的 Numpy 表示。
仅返回 DataFrame 中的值,轴标签将被移除。
它不再提及NDFrame - 而只是提及“DataFrame 的 NumPy 表示”。 NumPy 表示可以是视图或副本!
文档还包含一个关于混合数据类型的Note:
注意事项
dtype 将是较低公分母的 dtype(隐式向上转换);也就是说,如果混合了 dtypes(甚至是数字类型),则将选择容纳所有类型的数据类型。如果您不处理积木,请谨慎使用。
例如如果 dtype 是 float16 和 float32,则 dtype 将向上转换为 float32。如果 dtype 是 int32 和 uint8,则 dtype 将向上转换为 int32。按照numpy.find_common_type() 约定,混合int64 和uint64 将产生float64 dtype。
从这些注释中可以明显看出,访问包含不同 dtype 的 DataFrame 的 values 可以(几乎)永远返回视图。仅仅是因为它需要将值放入“最低公分母”dtype 的数组中,并且涉及到副本。
但是它没有说明视图/复制行为,这是设计使然。 jreback 在 pandas 问题跟踪器 1 中提到这实际上只是一个实现细节:
这是一个实现细节。由于您获得的是单个 dtyped numpy 数组,因此它被向上转换为兼容的 dtype。如果你有混合 dtypes,那么你几乎总是会有一个副本(例外是混合浮点 dtypes 不会复制我认为),但这是一个 numpy 细节。
我同意这不是很好,但它从一开始就存在,并且在当前的 pandas 中不会改变。如果导出到 numpy,你需要小心。
即使Series 的文档也没有提及视图:
pandas.Series.values
根据 dtype 以 ndarray 或类似 ndarray 的形式返回 Series
它甚至提到它甚至可能不会返回一个普通数组,具体取决于 dtype。这当然包括它返回副本的可能性(即使只是假设)。它不保证您能看到。
.values 何时返回视图,何时返回副本?
答案很简单:这是一个实现细节,只要是一个实现细节,就不会有任何保证。它是一个实现细节的原因是因为 pandas 开发人员希望确保他们可以根据需要更改内部存储。
但是在某些情况下,创建视图是不可能的。例如,使用包含不同 dtype 列的 DataFrame。
如果您分析迄今为止的行为,可能会有好处。但只要这是一个实现细节,无论如何你都不应该真正依赖它。
但是,如果您有兴趣:Pandas 当前在内部存储具有与多维数组相同的 dtype 的列。这样做的好处是您可以非常有效地对行和列进行操作(至少只要它们具有相同的 dtype)。但是如果 DataFrame 包含混合类型,它将有几个内部多维数组。每个 dtype 一个。无法创建指向两个不同数组的视图(至少对于 NumPy),因此当您混合 dtype 时,您将在需要 values 时获得副本。
旁注,你的例子:
df = pd.DataFrame([["A", "B"],["C", "D"]])
df.values[0][0] = 0
不是混合数据类型。它有一个特定的 dtype:object。但是object 数组可以包含任何 Python 对象,所以我明白你为什么会说/假设它是混合类型的。
个人笔记:
就我个人而言,我更希望values 属性仅在它无法返回视图时才返回视图或错误,以及仅返回副本的附加方法(例如as_array),即使有可能获得看法。这肯定会使行为更可预测,并避免一些意外,例如让属性进行昂贵的复制肯定是出乎意料的。
1这个问题已经在issue post中提到了,所以文档可能因为这个问题而改变了。