与面具Python的趋势

时间:2017-04-20 14:32:15

标签: python numpy curve-fitting

我有file,其内容如下:

data1 = np.loadtxt('lc1.out') 
x = data1[:, 0]
y = data1[:, 1] 

untreand

我想说道,我发现了一个非常有用的链接here

model = np.polyfit(x, y, 2)
predicted = np.polyval(model, x)

无论如何,我想屏蔽一部分数据,例如我只使用掩码外的点来适应。例如,我想只使用低于639.5且大于641.5的数据和二阶多项式拟合。

我有使用ma.masked_outside(x, 639.5, 641.5)的想法,因为它很容易只在数组中保存掩码之外的元素......但我不明白如何使用polyfit进行投射。

1 个答案:

答案 0 :(得分:4)

可能没有什么理由为您的用例使用屏蔽数组,除非出于性能原因或进一步使用屏蔽。因此,我将展示如何使用和不使用蒙版数组。

但是,为了获得参考,让我们首先在没有屏蔽的情况下发现:

无掩蔽的二阶多项式去除

import numpy as np
import matplotlib.pyplot as plt

data1 = np.loadtxt('lc1.out')
x, y = data1.T

fig = plt.figure()

plt.subplot(2, 1, 1)
plt.title('polyfit, original data set')
plt.plot(x, y, 'c.')

coeff = np.polyfit(x, y, 2)

# no need to use the original x values here just for visualizing the polynomial
x_poly = np.linspace(x.min(), x.max())
y_poly = np.polyval(coeff, x_poly)
plt.plot(x_poly, y_poly, 'r-', linewidth=3)

mid = len(x_poly) // 2
plt.annotate('y = {:.7g} x\xB2 + {:.7g} x + {:.7g}'.format(*coeff),
             (x_poly[mid], y_poly[mid]), (0, 48), textcoords='offset points',
             arrowprops={'arrowstyle': '->'}, horizontalalignment='center')

plt.subplot(2, 1, 2)
plt.title('detrended')

# we need the original x values here, so we can remove the trend from all points
trend = np.polyval(coeff, x)
# note that simply subtracting the trend might not be enough for other data sets
plt.plot(x, y - trend, 'b.')
fig.show()

second order polynomial detrending without masking

记下多项式的系数。

二阶多项式去趋势,选择有效点

我们可以简单地创建仅包含所需点的新 x y 数组。这里的错误可能性较小。

这分三步进行。首先,我们在感兴趣的数组上使用比较运算符,这会产生一个带有' True'比较为真的指数的值和“假”。其他地方的价值观。

然后我们将bool数组放入' np.where()',这会产生一个数组,其中包含所有索引号作为bool数组具有的真值' True'价值观,我即它正在回答这个问题:"我的阵列在哪里?"

最后我们仔细阅读Numpy的高级索引并将我们的结果索引数组作为索引应用于 x y 数组,这些数组会滤除所有不需要的数据指数。

import numpy as np
import matplotlib.pyplot as plt

data1 = np.loadtxt('lc1.out')
x, y = data1.T
select = np.where((x < 640.75) | (x > 641.25))
x_selection = x[select]  # numpy advanced indexing
y_selection = y[select]  # numpy advanced indexing

fig = plt.figure()

plt.subplot(2, 1, 1)
plt.title('polyfit, selecting significant points')
plt.plot(x_selection, y_selection, 'c.')

coeff = np.polyfit(x_selection, y_selection, 2)

# no need to use the original x values here just for visualizing the polynomial
x_poly = np.linspace(x_selection.min(), x_selection.max())
y_poly = np.polyval(coeff, x_poly)
plt.plot(x_poly, y_poly, 'r-', linewidth=3)

mid = len(x_poly) // 2
plt.annotate('y = {:.7g} x\xB2 + {:.7g} x + {:.7g}'.format(*coeff),
             (x_poly[mid], y_poly[mid]), (0, 48), textcoords='offset points',
             arrowprops={'arrowstyle': '->'}, horizontalalignment='center')

plt.subplot(2, 1, 2)
plt.title('detrended')

# we need the original x values here, so we can remove the trend from all points
trend = np.polyval(coeff, x)
# note that simply subtracting the trend might not be enough for other data sets
plt.plot(x, y - trend, 'b.')
fig.show()

second order polynomial detrending, selecting significant points

正如预期的那样,系数现在不同了。

二阶多项式去趋势,掩蔽不需要的点

当然我们也可以使用蒙面数组。注意反向逻辑:蒙面点是我们不想要的点。如示例数据中我们不想要间隔内的点数,我们使用ma.masked_inside()

如果出于性能原因我们想避免创建原始数组的完整副本,我们可以使用关键字copy=False。使原始数组以只读方式使我们不会通过改变原始数组而意外更改掩码数组中的值。

对于蒙版数组,我们需要使用polyfit()子模块中numpy.ma函数的版本,该函数正确地忽略了掩码版 x 中不需要的值以及未屏蔽的伴随数组 y 。如果我们不这样做,我们会得到错误的结果。请注意,这是一个很容易犯的错误,所以如果我们可以提供帮助,我们可能会想要坚持使用其他方法。

import numpy as np
import numpy.ma as ma
import matplotlib.pyplot as plt

data1 = np.loadtxt('lc1.out')
x, y = data1.T
x.flags.writeable = False  # safety measure, as we don't copy
x_masked = ma.masked_inside(x, 640.75, 641.25, copy=False)

fig = plt.figure()

plt.subplot(2, 1, 1)
plt.title('polyfit, masking unwanted points')
plt.plot(x_masked, y, 'c.')

coeff = ma.polyfit(x_masked, y, 2)

# no need to use the original x values here just for visualizing the polynomial
x_poly = np.linspace(x_masked.min(), x_masked.max())
y_poly = np.polyval(coeff, x_poly)
plt.plot(x_poly, y_poly, 'r-', linewidth=3)

mid = len(x_poly) // 2
plt.annotate('y = {:.7g} x\xB2 + {:.7g} x + {:.7g}'.format(*coeff),
             (x_poly[mid], y_poly[mid]), (0, 48), textcoords='offset points',
             arrowprops={'arrowstyle': '->'}, horizontalalignment='center')

plt.subplot(2, 1, 2)
plt.title('detrended')

# we need the original x values here, so we can remove the trend from all points
trend = np.polyval(coeff, x)
# note that simply subtracting the trend might not be enough for other data sets
plt.plot(x, y - trend, 'b.')
fig.show()

second order polynomial detrending, masking unwanted points

系数与其他方法相同,这是好的。如果我们错误地使用了np.polyfit(),我们最终会得到与未屏蔽引用相同的系数。