Python DataFrame.values中的更改是否总是修改数据框中的值?

Python DataFrame.values中的更改是否总是修改数据框中的值?,python,pandas,numpy,dataframe,Python,Pandas,Numpy,Dataframe,在文件上,它说 NDFrame的Numpy表示-- “NDFrame的Numpy表示”是什么意思?修改这个numpy表示会影响我的原始数据帧吗?换句话说,将。值返回副本或视图 StackOverflow中有一些问题的答案,暗示(依赖于)返回视图。例如,在的公认答案中,np.fill_diagonal(df.values,0)用于将df对角线部分的所有值设置为0。这是在本例中返回的视图。但是,如中所示,有时会返回副本。 这感觉很基本。这对我来说有点奇怪,因为我没有更详细的.values的来源 除

在文件上,它说

NDFrame的Numpy表示--

“NDFrame的Numpy表示”是什么意思?修改这个numpy表示会影响我的原始数据帧吗?换句话说,
。值
返回副本或视图

StackOverflow中有一些问题的答案,暗示(依赖于)返回视图。例如,在的公认答案中,
np.fill_diagonal(df.values,0)
用于将
df
对角线部分的所有值设置为0。这是在本例中返回的视图。但是,如中所示,有时会返回副本。

这感觉很基本。这对我来说有点奇怪,因为我没有更详细的
.values
的来源


除了@coldspeed答案中的当前实验之外,还返回一个视图的另一个实验:

df = pd.DataFrame([["A", "B"],["C", "D"]])

df.values[0][0] = 0
我们得到

df
    0   1
0   0   B
1   C   D
即使它现在是混合类型,我们仍然可以通过设置
df.values

df.values[0][1] = 5
df
    0   1
0   0   5
1   C   D
让我们测试一下

首先,使用
pd.Series
对象

In [750]: s = pd.Series([1, 2, 3])

In [751]: v = s.values

In [752]: v[0] = 10000

In [753]: s
Out[753]: 
0    10000
1        2
2        3
dtype: int64
现在,对于
DataFrame
对象。首先,考虑非混合<代码> dType >代码> -/P>
In [780]: df = pd.DataFrame(1 - np.eye(3, dtype=int))

In [781]: df
Out[781]: 
   0  1  2
0  0  1  1
1  1  0  1
2  1  1  0

In [782]: v = df.values

In [783]: v[0] = 12345

In [784]: df
Out[784]: 
       0      1      2
0  12345  12345  12345
1      1      0      1
2      1      1      0
In [755]: df = pd.DataFrame({'A' :[1, 2], 'B' : ['ccc', 'ddd']})

In [756]: df
Out[756]: 
   A    B
0  1  ccc
1  2  ddd

In [757]: v = df.values

In [758]: v[0] = 123

In [759]: v[0, 1] = 'zzxxx'

In [760]: df
Out[760]: 
   A    B
0  1  ccc
1  2  ddd
进行了修改,这意味着
。值
返回了一个视图

现在,考虑一个具有混合<代码> dType < /C> > /P>的场景。

In [780]: df = pd.DataFrame(1 - np.eye(3, dtype=int))

In [781]: df
Out[781]: 
   0  1  2
0  0  1  1
1  1  0  1
2  1  1  0

In [782]: v = df.values

In [783]: v[0] = 12345

In [784]: df
Out[784]: 
       0      1      2
0  12345  12345  12345
1      1      0      1
2      1      1      0
In [755]: df = pd.DataFrame({'A' :[1, 2], 'B' : ['ccc', 'ddd']})

In [756]: df
Out[756]: 
   A    B
0  1  ccc
1  2  ddd

In [757]: v = df.values

In [758]: v[0] = 123

In [759]: v[0, 1] = 'zzxxx'

In [760]: df
Out[760]: 
   A    B
0  1  ccc
1  2  ddd
这里,
.values
返回一个副本


观察

.values
for Series返回一个视图,与每行的数据类型无关,而对于数据帧则取决于此。对于同质数据类型,将返回一个视图。否则,一份副本。

TL;博士:

如果返回副本(那么更改值不会改变数据帧),或者如果
返回视图(那么更改值会改变数据帧),则这是一个实现细节。不要依赖这些案例中的任何一个。如果开发人员认为这是有益的(例如,如果他们改变了DataFrame的内部结构),那么它可能会改变


我想,自从提出这个问题以来,文档已经发生了变化,目前的内容是:

pandas.DataFrame.values
返回数据帧的Numpy表示形式

仅返回数据框中的值,轴标签将被删除

它不再提到
NDFrame
,而是简单地提到了“数据帧的NumPy表示”。NumPy表示可以是视图或副本

本文档还包含关于混合数据类型的
注释

笔记 数据类型将是较低的公分母数据类型(隐式向上转换);也就是说,如果数据类型(即使是数字类型)是混合的,那么将选择一个容纳所有数据类型的数据类型。如果不处理块,请小心使用

e、 g.如果数据类型为float16和float32,则数据类型将向上转换为float32。如果数据类型为int32和uint8,则数据类型将向上转换为int32。按照
numpy.find_common_type()
约定,混合使用int64和uint64将生成float64数据类型

从这些注释中可以明显看出,访问包含不同数据类型的数据帧的
(几乎)永远不会返回视图。这仅仅是因为它需要将值放入“最小公分母”数据类型的数组中,这涉及到一个副本

但是,它没有说明任何有关查看/复制行为的内容,这是出于设计。在pandas问题跟踪程序1中提到,这实际上只是一个实施细节:

这是一个实现细节。因为您得到的是一个数据类型的numpy数组,所以它被向上转换为一个兼容的数据类型。如果您有混合数据类型,那么您几乎总是会有一个副本(我认为混合浮点数据类型不会复制是个例外),但这是一个基本细节

我同意这不是很好,但它从一开始就存在,在现在的大熊猫中不会改变。如果要导出到numpy,您需要小心

即使是
系列的文档
也没有提到视图:

pandas.Series.values
根据数据类型将序列返回为ndarray或类似ndarray

它甚至提到,根据数据类型,它甚至可能不会返回普通数组。这当然包括它返回副本的可能性(即使只是假设)。这并不保证你能看到风景


.values
何时返回视图,何时返回副本? 答案很简单:这是一个实现细节,只要是一个实现细节,就不会有任何保证。它之所以是一个实现细节,是因为pandas开发人员希望确保,如果他们愿意,他们可以更改内部存储。 但是在某些情况下,不可能创建视图。例如,使用包含不同数据类型列的数据帧

如果分析到目前为止的行为,可能会有好处。但只要这是一个实现细节,你就不应该真正依赖它

但是,如果您感兴趣,Pandas当前在内部存储与多维数组具有相同数据类型的列。这样做的好处是可以非常高效地对行和列进行操作(至少只要它们具有相同的数据类型)。但是,如果数据帧包含混合类型,它将具有多个内部多维数组。每个数据类型一个。不可能创建指向两个不同数组的视图(至少对于NumPy),因此当您使用混合数据类型时,您可以在需要
值时获得副本


一个旁注,你的例子:

df = pd.DataFrame([["A", "B"],["C", "D"]])

df.values[0][0] = 0
不是混合数据类型。它有一个特定的数据类型:
对象
。但是
object
数组可以包含任何Python对象,