【发布时间】:2018-01-28 09:31:11
【问题描述】:
我有一些这样的实验数据:
x = array([1, 1.12, 1.109, 2.1, 3, 4.104, 3.1, ...])
y = array([-9, -0.1, -9.2, -8.7, -5, -4, -8.75, ...])
z = array([10, 4, 1, 4, 5, 0, 1, ...])
如果方便的话,我们可以假设数据以3D数组甚至pandas的形式存在DataFrame:
df = pd.DataFrame({'x': x, 'y': y, 'z': z})
解释是,对于每个位置x[i], y[i],某个变量的值是z[i]。这些是不是均匀采样的,所以会有一些“密集采样”的部分(例如x 中的 1 到 1.2 之间)和其他非常稀疏的部分(例如 @ 中的 2 到 3 之间987654328@)。正因为如此,我不能只将这些放入 pcolormesh 或 contourf。
我想要做的是以某个固定间隔对x 和y 进行平均重新采样,然后聚合z 的值。对于我的需要,z 可以求和或平均以获得有意义的值,所以这不是问题。我的幼稚尝试是这样的:
X = np.arange(min(x), max(x), 0.1)
Y = np.arange(min(y), max(y), 0.1)
x_g, y_g = np.meshgrid(X, Y)
nx, ny = x_g.shape
z_g = np.full(x_g.shape, np.nan)
for ix in range(nx - 1):
for jx in range(ny - 1):
x_min = x_g[ix, jx]
x_max = x_g[ix + 1, jx + 1]
y_min = y_g[ix, jx]
y_max = y_g[ix + 1, jx + 1]
vals = df[(df.x >= x_min) & (df.x < x_max) &
(df.y >= y_min) & (df.y < y_max)].z.values
if vals.any():
z_g[ix, jx] = sum(vals)
这行得通,我得到了我想要的输出,plt.contourf(x_g, y_g, z_g),但它很慢!我有大约 2 万个样本,然后我将其二次采样为 x 中的约 800 个样本和 y 中的约 500 个样本,这意味着 for 循环的长度为 40 万。
有没有办法对它进行矢量化/优化?如果有一些功能已经做到了,那就更好了!
(也将其标记为 MATLAB,因为 numpy/MATLAB 之间的语法非常相似,我可以访问这两个软件。)
【问题讨论】:
-
pandas 中可能的解决方案:stackoverflow.com/questions/42689070/…(虽然可能不如下面的 numpy 解决方案高效)。
标签: python matlab numpy matplotlib contourf