我在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)
在一开始。
答案 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
中创建矩阵。您是从“系列”的元素中制作出来的。