我有一段 Python 代码已经使用了大约一年,没有任何问题(它读取、解压缩/解压缩数据、选择一个窗口并使用 Numpy/Matplotplib 绘制它)。
我们最近得到了一台新机器,它以 64 位编码格式存储数据,而不是 32 位编码,这应该不是一个真正的问题。我重写了几行代码来处理这个问题(感兴趣的两个函数都包含在下面),但我一直收到一个我不太理解的错误。
错误:
Traceback (most recent call last):
File "./3D_Visualizer.py", line 238, in <module>
File "./3D_Visualizer.py", line 232, in main
main()
File "./3D_Visualizer.py", line 93, in plot_data
ax.set_ylabel('Time (s)',color='r')
File "/usr/lib/python2.7/dist-packages/numpy/core/fromnumeric.py", line 170, in reshape
return _wrapit(a, 'reshape', newshape, order=order)
File "/usr/lib/python2.7/dist-packages/numpy/core/fromnumeric.py", line 37, in _wrapit
result = getattr(asarray(obj),method)(*args, **kwds)
ValueError: total size of new array must be unchanged
如果有人能够向我解释为什么会发生此错误,我会很高兴,因为我理解 numpy reshape 函数将输入数组的大小用于实际调整大小。下面列出了导致此错误的 2 个函数的代码:
阅读功能:
def numpy_array(data, peaks):
"""Fills the NumPy array 'data' with m/z-intensity values acquired
from b64 decoding and unpacking the binary string read from the
mzXML file, which is stored in the list 'peaks'.
The m/z values are assumed to be ordered without validating this
assumption.
Note: This function is the performance bottleneck
"""
rt_counter=0
for x in peaks:
if rt_counter %(len(peaks)/20) == 0:
update_progress()
peak_counter=0
data_buff=base64.b64decode(x)
endian = '!'
precision = 'd'
buff_size = len(data_buff) / struct.calcsize(endian + precision)
index=0
for y in struct.unpack(endian + precision * buff_size, data_buff[0:len(data_buff)]):
if (index % 2 == 0):
data[rt_counter][1][peak_counter][0]= y
else:
data[rt_counter][1][peak_counter][1]= y
peak_counter+=1
index+=1
rt_counter+=1
绘图功能:
def plot_data(X,Y,Z):
"""Plots a 3D wireframe based on the x, y and z datapoints passed
to this function in the python lists 'X', 'Y' and 'Z'. Custom
labels are created for the Y (m/z) axis since matplotlib creates
'ugly' labels by default (TODO: labelling goes wrong).
"""
fig=plt.figure()
x=sorted(set(X))
y=sorted(set(Y))
labels=['%.2f'%k for k in y]
XX,YY=np.meshgrid(y,x)
ZZ=np.reshape(Z,XX.shape)
ax=fig.add_subplot(111,projection='3d')
ax.plot_wireframe(XX,YY,ZZ)
ax.set_title('3D projection of LC-MS region',size='large',color='r')
ax.set_xlabel('m/z',color='r',style='italic')
ax.set_xticklabels(labels)
ax.set_ylabel('Time (s)',color='r')
ax.set_zlabel('Intensity',color='r')
plt.show()
-- 2013 年 7 月 30 日 2:10 --
在抛出此错误的测试用例中,X、Y 和 Z 的长度都相同(即 184)。x 和 y 的长度set
在错误测试用例中分别为 18 和 20 行,而set
在工作测试用例中它们分别为 18 和 11 行。
错误情况下的示例内容y
(64 位编码):
[1398.51513671875, 1398.5152587890625, 1398.5225830078125, 1398.522705078125, 1398.530029296875, 1398.5301513671875, 1398.5374755859375, 1398.53759765625, 1398.5447998046875, 1398.544921875, 1398.55224609375, 1398.5523681640625, 1398.5596923828125, 1398.559814453125, 1398.567138671875, 1398.5672607421875, 1398.5745849609375, 1398.5819091796875, 1398.58203125, 1398.58935546875]
工作案例中“y”的示例内容(32 位编码):
[1398.51171875, 1398.5191650390625, 1398.526611328125, 1398.533935546875, 1398.5413818359375, 1398.548828125, 1398.5562744140625, 1398.5635986328125, 1398.571044921875, 1398.5784912109375, 1398.5859375]
这表明在错误情况下,我认为解码在拟合值方面存在问题?
-- 2013 年 7 月 31 日 10:20 --
我深入研究从实际机器获取的原始数据,结果表明所有时间点的测量坐标都不相同(所有先前版本的机器+控制软件都是这种情况)。这会导致某些坐标稍微移动一点(即 1398.5152... 与 1398.5151),从而导致重塑失败。
我目前正在将每个坐标分配给一个整数值 (1, 2 ...) 以暂时“修复”这个问题。