Python DataFrame.values中的更改是否总是修改数据框中的值?
在文件上,它说 NDFrame的Numpy表示-- “NDFrame的Numpy表示”是什么意思?修改这个numpy表示会影响我的原始数据帧吗?换句话说,将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的来源 除
。值
返回副本或视图
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对象,