【问题标题】:Fit a line to a matrix in python将一条线拟合到python中的矩阵
【发布时间】:2014-11-22 19:37:36
【问题描述】:

我有一个形状为 256x256 的矩阵,我试图找到一条最适合的线。顺便说一下,这是一张图像,所以这些只是强度值。假设我想通过所有强度找到最适合的线,我将如何去做? This 链接描述了如何使用 svd 在 3d 数据集上执行此操作。但是,我对如何将其应用于我的 numpy 数组感到有些困惑?

编辑:这是我用 %timeit 分析的双精度随机值的示例:

ran = [25,50,75,100,125]
for i in ran:                                                                                 
    J = np.random.random((i,i))                                                     
    y,x=np.indices(J.shape)                                                                   
    x = x.ravel()                                                                             
    y = y.ravel()                                                                             
    J=J.ravel()                                                                               
    data = np.concatenate((x[:, np.newaxis],
                          y[:, np.newaxis],
                          J[:, np.newaxis]),axis=1)        
    datamean = data.mean(axis=0)                                                              
    print "Doing %d now"  %i                                                                    
    %timeit U, S, V = np.linalg.svd(data - datamean) 

我得到以下输出:

Doing 25 now
100 loops, best of 3: 10.4 ms per loop
Doing 50 now
1 loops, best of 3: 285 ms per loop
Doing 75 now
1 loops, best of 3: 3 s per loop
Doing 100 now
1 loops, best of 3: 5.83 s per loop
Doing 125 now
1 loops, best of 3: 15.1 s per loop

EDIT2:Here's my actual array。我只是用numpy的npy格式保存的

【问题讨论】:

    标签: python arrays numpy matplotlib curve-fitting


    【解决方案1】:

    The answer you pointed out 直接适用于您的问题:

    import numpy as np
    
    z = your_matrix_256_x_256
    y, x = np.indices(z.shape)
    x = x.ravel()
    y = y.ravel()
    z = z.ravel()
    

    请注意,xy 的间隔可以通过将这些数组乘以适当的标量来重新调整。


    编辑:

    查看您的数据似乎更多的是您的问题是二维曲线拟合,这可以通过np.polyfit() 完成,如下例所示。

    z = np.load('arr.npy').astype(np.int32)
    y, x = np.indices(z.shape)
    valid_z = (y.ravel()>0) & (z.ravel()>0)
    x_valid = x.ravel()[valid_z]
    y_valid = y.ravel()[valid_z]
    z_valid = z.ravel()[valid_z]
    # fitting best curve
    fig = plt.figure(figsize=(5,3))
    ax = fig.add_subplot(111)
    ax.scatter(x_valid, y_valid, c=z_valid, alpha=0.2, s=20, edgecolor='none',
            cmap=plt.cm.jet)
    # finding best-fit curve
    z = np.polyfit(x_valid, y_valid, w=z_valid**0.5, deg=1)
    p = np.poly1d(z)
    # plotting
    x_plot = np.linspace(x_valid.min(), x_valid.max(), 100)
    y_plot = p(x_plot)
    ax.plot(x_plot, y_plot, '-r', lw=2)
    ax.set_xlim(0, x.shape[1])
    ax.set_ylim(0, y.shape[0])
    
    ax.legend(loc='lower left', frameon=False, fontsize=8)
    fig.savefig('test.png', bbox_inches='tight')
    

    给出:

    【讨论】:

    • 啊,非常感谢!
    • 哇,这个例程需要很长时间才能运行。 2小时过去了,正常吗?我在联合直方图图像上进行了尝试,因此使用 dtype float64 的 256x256 np 数组。
    • @benbran 我从未尝试过参考答案的例程...您能以某种方式提供您的矩阵,以便我可以使用新例程进行测试吗?
    • 对不起,我没有读到你想要实际的矩阵。我通过 Dropbox 链接提供了它
    • @benbran 我创建了this Gist on GitHub,并提供了一个我认为很有希望的解决方案……你能试试吗?
    【解决方案2】:

    您可以通过避免复制您的数据和adjusting your weights 来考虑复制的观察结果,从而获得更快的结果。我也忽略了聚集在数据底部边缘的可能坏数据。

    import numpy
    import matplotlib.pyplot as plt
    
    # Load the data
    arr = numpy.load('arr.npy')
    
    # Extract the counts from the data
    data = numpy.array([(j, i, n) for (i, j), n in numpy.ndenumerate(arr)
                                  if n != 0.0 and i > 0])
    x, y, n = data.T
    weight = numpy.sqrt(n)
    
    # Fit the data, weighting appropriately for the number of points
    p = numpy.polyfit(x, y, 1, w=weight)
    
    # Evaluate the polynomial - this is here to make it easier to use
    # other orders
    smoothx = numpy.linspace(x.min(), x.max(), 100)
    smoothy = numpy.polyval(p, smoothx)
    
    # Plot the data and the fit
    plt.pcolor(numpy.log(arr+1))
    plt.plot(smoothx, smoothy, color='red', linewidth=2)
    plt.xlim([0, 255])
    plt.ylim([0, 255])
    plt.show()
    

    【讨论】:

    • +1 感谢您提供有关使用权重的提示...我不知道此功能...
    猜你喜欢
    • 1970-01-01
    • 2016-04-23
    • 2012-08-19
    • 2018-03-22
    • 2021-06-14
    • 1970-01-01
    • 1970-01-01
    • 2021-04-21
    • 2017-07-19
    相关资源
    最近更新 更多