1

我有一段 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 ...) 以暂时“修复”这个问题。

4

1 回答 1

2

也许不是真正的答案,但评论字段有些有限:

我发现回溯很奇怪:它从ax.set_ylabelto跳转return _wrapit(a, 'reshape', newshape, order=order),在 matplotlib 内部没有任何中间调用(例如,我希望fromnumeric.reshape从inside 调用。你的代码中set_ylabel唯一出现的是reshape

ZZ=np.reshape

所以也许罪魁祸首是,不知何故,订单在回溯中搞砸了。

ZZ=np.reshape(Z,XX.shape)

如果Z并且XX具有不兼容的形状,则失败。我假设XY并且Z在调用时确实具有兼容的形状plot_data()。因为XX是在meshgrid()调用中创建的,y或者x可能有不正确的尺寸。由于xandy是通过调用 and 创建的,set()这可能是出错的地方:值多次出现或可能会搞砸事情,即使这一切都涉及浮点值。XYXY

所以我会验证 、 和 的形状(长度)XY然后Z验证x和的形状(长度) y

我注意到一个

unpack_format=">%dL" % buff_size`

这条线表明数据实际上是长整数,而不是浮点数(更容易遇到值多次出现的问题)。话又说回来,unpack_format是无处使用。

于 2013-07-30T11:31:15.963 回答