numpy.matrix忽略副本

时间:2018-08-08 15:38:56

标签: python pandas numpy

我在pandas数据框中有一个列,该列本身包含numpy数组(我知道,可能不是最好的主意,但我现在很好奇)。在此列的副本上调用numpy.matrix会更改原始数据帧:

import numpy as np
import pandas as pd

array = [np.array([1, 2])]

df = pd.DataFrame({
    'arrays': array.copy()  # creating a copy here...
})
df_backup = df.copy(deep=True)  # ... and here
df

这返回了我期望的结果:

   arrays
0  [1, 2]

以后需要比较的几件事:

>>> array
[array([1, 2])]
>>> array[0].shape
(2,)

现在,我尝试将其转换为矩阵。它并没有执行我想要的操作,但是我的意思是,它会更改数据,但据我所知应该不行:

>>> np.matrix(df.arrays.copy(), copy=True)  # another copy
matrix([[array([[1],
       [2]])]], dtype=object)

这是很奇怪的地方:

>>> df
       arrays
0  [[1], [2]]

以某种方式,我的单元格现在拥有一个数组,其中每个元素都是一个只有一个数字的数组,而之前是一个只有两个数字的单个数组。即使我告诉np.matrix(..., copy=True) 并且制作了我的熊猫系列:df.arrays.copy()的副本,还是发生了这种情况。

>>> df_backup
       arrays
0  [[1], [2]]

即使我早先进行的备份也已更改。我什至使用了深拷贝。

这是最让我感到困惑的部分:我的原始列表也被更改了。 (也称为.copy()。)

>>> array
[array([[1],
       [2]])]
>>> array[0].shape
(2, 1)

所以现在我的问题是,在所有这些副本之后,如何仍将所有内容链接在一起,并且我还需要做些什么才能真正不更改原始数据?

编辑:

所以看来答案是熊猫只存储对numpy对象的引用,甚至在

from copy import deepcopy
df_backup = deepcopy(df)

df_backup仍被修改。

array不被修改的唯一方法是如果我做类似的事情

array_backup = deepcopy(array)

在一开始。

1 个答案:

答案 0 :(得分:1)

首先,一个包含数组的列表:

In [334]: alist = [np.array([1,2])]

该列表中的数据框:

In [335]: df = pd.DataFrame({'arrays':alist})
In [336]: df
Out[336]: 
   arrays
0  [1, 2]

p Series

In [337]: df.arrays
Out[337]: 
0    [1, 2]
Name: arrays, dtype: object

Series的元素:

In [338]: df.arrays[0]
Out[338]: array([1, 2])

从该数组制作矩阵-它是一个副本(默认参数)

In [339]: mat = np.matrix(df.arrays[0])
In [340]: mat
Out[340]: matrix([[1, 2]])
In [341]: df
Out[341]: 
   arrays
0  [1, 2]
In [342]: alist
Out[342]: [array([1, 2])]

Series制作矩阵:

In [343]: mat2 = np.matrix(df.arrays)
In [344]: mat2
Out[344]: 
matrix([[array([[1],
       [2]])]], dtype=object)
In [345]: alist
Out[345]: 
[array([[1],
        [2]])]
In [346]: mat2.shape
Out[346]: (1, 1)

mat2是一个(1,1)矩阵(矩阵始终为2d),即对象dtype-即它包含一个对象,在这种情况下为数组。

创建mat2已将alist中的元素替换为(2,1)数组。 df也有一个指向这个新数组的指针。 (编辑-进一步挖掘,似乎创建mat2只是重塑了alist中的数组。)

我不确定是什么原因创建了这个(2,1)数组,但是我怀疑它与Series如何将其元素传递给np.matrix有关。无论如何,您都不想直接从Series中创建矩阵。您是从“系列”的元素中制作出来的。