Jam*_*sel 0 python memory numpy shared-memory python-3.x
我有一些代码,我一生都无法弄清楚这些是如何共享内存的!!!!所有测试都是错误的(如图所示),然而,内存位置在功能上和视觉上似乎都相同。我花了几个小时试图排除故障,但无法弄清楚。 请帮忙!!!为什么这些阵列共享内存!??
listOfValues和listOfxValues在不应该共享内存时共享内存。
警告:丑陋,丑陋的代码,我很抱歉,这是艰难的一天。
listOfLists = []
splitold=0
#split arrays into each bin
for split in splitInd:
splitnew=split
listOfLists.append(xind[splitold:splitnew])
splitold=split
listOfValues = np.array(listOfLists.copy())
#convert to float type
for i,lst in enumerate(listOfValues):
listOfValues[i] = lst.astype(float)
listOfxValues = np.copy(listOfValues)
#PRINT TROUBLESHOOTING
print(listOfxValues.data)
print(listOfValues.data)
print(listOfValues is listOfxValues)
print(listOfValues == listOfxValues)
print(listOfValues.data is listOfxValues.data)
print(listOfValues.data == listOfxValues.data)
print(np.shares_memory(listOfxValues,listOfValues))
print(listOfxValues.__array_interface__['data'][0] == listOfValues.__array_interface__['data'][0])
print(listOfxValues.__array_interface__['data'][0] == listOfValues.__array_interface__['data'][0])
#exchange indexed values for real values
for each in range(len(listOfValues)):
for i,index in enumerate(listOfLists[each]):
listOfxValues[each][i] = xdata[index]
listOfValues[each][i] = ydata[index]
maxArrayInd = []
#get max indices
for array in listOfValues:
maxArrayInd.append(np.argmax(array))
maxX = []
maxY = []
#get values for max indices
for idx,mx in enumerate(maxArrayInd):
maxX.append(listOfxValues[idx][mx])
maxY.append(listOfValues[idx][mx])
Run Code Online (Sandbox Code Playgroud)
此代码输出:
<memory at 0x00000215644C5640>
<memory at 0x00000215644C5640>
False
False
False
False
False
False
False
Run Code Online (Sandbox Code Playgroud)
尽管所有测试结果都是错误的,但内存位置显然是相同的。它打破了我的代码。请帮忙!!
谢谢你,请原谅我的绝望。
编辑:
我无法弄清楚为什么它会这样,但移动
listOfxValues = np.copy(listOfValues)
Run Code Online (Sandbox Code Playgroud)
以上 #convert to float 类型修复了错误。我仍然无法弄清楚他们为什么要共享内存,以及为什么要解决这个问题。我理解指针、视图、副本等之间的区别(至少是基本的理解),但这仍然没有意义,为什么我遇到了问题。
感谢您的所有回答!我至少学到了一些!
的.data属性是一个memoryview对象。每次访问属性时都会创建一个新memoryview的。 打印时显示memoryview的地址是 Python 对象的地址,而不是数组中底层数据的地址。
当 Python 执行时print(listOfxValues.data),访问.data属性会触发 NumPy 代码,该代码创建一个新memoryview对象,并将该对象传递给print(). 调用print()完成后,不再有任何 Python 对象持有对 的引用memoryview,因此垃圾收集器可以将其释放。然后,当您调用 时print(listOfValues.data),memoryview会创建一个新对象,但结果是 Python 碰巧重用了之前调用中使用过的相同内存。
如果你这样做:
a = listOfxValues.data
b = listOfValues.data
print(a)
print(b)
Run Code Online (Sandbox Code Playgroud)
两个memoryviews的内存地址总是不同的。如果a和b是通过访问同一数组的.data属性创建的,则也是如此,例如
In [23]: x = np.array([1, 2, 3, 4])
In [24]: a = x.data
In [25]: b = x.data
In [26]: a
Out[26]: <memory at 0x120975050>
In [27]: b
Out[27]: <memory at 0x120808c80>
Run Code Online (Sandbox Code Playgroud)