在我的Python代码中,我总是使用一种模式进行分析 数值数据。所有实现都显得过于冗余或非常繁琐 只是不要与NumPy功能很好地配合。我想找到一个更好的方法 抽象这种模式。
统计错误传播的方法是引导方法。它的工作原理 使用稍微不同的输入多次运行相同的分析并查看 最终结果的分布。
要计算ams_phys
的实际值,我有以下等式:
ams_phys = (amk_phys**2 - 0.5 * ampi_phys**2) / aB - amcr
进入该等式的所有值都存在相关的统计误差
用它。这些值也可以从其他方程计算出来。例如
amk_phys
是根据这个等式计算的,其中两个数字也有
不确定性:
amk_phys_dist = mk_phys / a_inv
mk_phys
的值在论文中给出为(494.2±0.3)。我现在做的是
参数化bootstrap 并从高斯分布生成R
个样本
平均值为494.2,标准差为0.3。这就是我存储的内容
mk_phys_dist
:
mk_phys_dist = bootstrap.make_dist(494.2, 0.3, R)
对于a_inv
也是如此,其中也引用了错误
文献。然后将上面的等式转换为列表理解以产生
一个新的发行版:
amk_phys_dist = [mk_phys / a_inv
for a_inv, mk_phys in zip(a_inv_dist, mk_phys_dist)]
然后第一个等式也被转换为列表理解:
ams_phys_dist = [
(amk_phys**2 - 0.5 * ampi_phys**2) / aB - amcr
for ampi_phys, amk_phys, aB, amcr
in zip(ampi_phys_dist, amk_phys_dist, aB_dist, amcr_dist)]
为了得到(值±误差)的最终结果,我接受平均值和 这种数字分布的标准差:
ams_phys_val, ams_phys_avg, ams_phys_err \
= bootstrap.average_and_std_arrays(ams_phys_dist)
实际值应该用实际值来计算,
不是这个bootstrap发行版的意思。在我复制代码之前
为此,现在我在_dist
的第0位有原始值
阵列。这些数组现在包含1 + R
个元素和
bootstrap.average_and_std_arrays
函数将该元素分开。
对于我可能想引用的每个数字,都会出现这种情况 写作。我对写作感到恼火并为它创建了一个片段:
$1_val, $1_avg, $1_err = bootstrap.average_and_std_arrays($1_dist)
对代码片段的需求强烈告诉我,我需要进行一些重构。 列表推导也总是具有以下模式:
foo_dist = [ ... bar ...
for bar in bar_dist]
在那里写三次bar
感觉不好。
我试图将这些_dist
内容设为Boot
类,这样我就不会这样做
写ampi_dist
和ampi_val
,但可以只使用ampi.val
显式调用此average_and_std_arrays
函数并键入一堆
它的名字。
class Boot(object):
def __init__(self, dist):
self.dist = dist
def __str__(self):
return str(self.dist)
@property
def cen(self):
return self.dist[0]
@property
def val(self):
x = np.array(self.dist)
return np.mean(x[1:,], axis=0)
@property
def err(self):
x = np.array(self.dist)
return np.std(x[1:,], axis=0)
然而,这仍然没有解决列表推导的问题。一世
我担心我还要在那里重复三次。我可以做到
Boot
对象继承自list
,因此我至少可以像写一样
这个(没有_dist
):
bar = Boot([... foo ... for foo in foo])
理想情况下,所有这些列表理解都会消失,以至于我可以 写
bar = ... foo ...
其中点表示一些非平凡的操作。那些可以是简单的算术 如上所述,但也可以是函数调用,而不是 支持使用多个值调用(如NumPy函数支持)。
例如,需要多次调用scipy.optimize.curve_fit
函数:
popt_dist = [op.curve_fit(linear, mpi, diff)[0]
for mpi, diff in zip(mpi_dist, diff_dist)]
必须为此编写一个包装器,因为它不会自动遍历数组列表。
您是否看到了一种方法来抽象运行每个转换的过程
1 + R
组数据?我想摆脱那些模式和巨大的
每个命名空间中的变量数量(_dist
,_val
,_avg
,...)就像这样
使它传递给相当乏味的功能。
我需要在... foo ...
部分获得很多自由
调用任意函数。