我计划在我正在编写的一些数字密集型科学代码中广泛使用 xarray。到目前为止,它使代码非常优雅,但我认为我将不得不放弃它,因为性能成本太高了。
这是一个示例,它创建两个数组并使用 xarray(具有多个索引方案)和 numpy 将它们的一部分相乘。我使用了 num_comp=2 和 num_x=10000:
Line # Hits Time Per Hit % Time Line Contents
4 @profile
5 def xr_timing(num_comp, num_x):
6 1 4112 4112.0 10.1 da1 = xr.DataArray(np.random.random([num_comp, num_x]).astype(np.float32), dims=['component', 'x'], coords={'component': ['a', 'b'], 'x': np.linspace(0, 1, num_x)})
7 1 438 438.0 1.1 da2 = da1.copy()
8 1 1398 1398.0 3.4 da2[:] = np.random.random([num_comp, num_x]).astype(np.float32)
9 1 7148 7148.0 17.6 da3 = da1.isel(component=0).drop('component') * da2.isel(component=0).drop('component')
10 1 6298 6298.0 15.5 da4 = da1[dict(component=0)].drop('component') * da2[dict(component=0)].drop('component') …Run Code Online (Sandbox Code Playgroud) 是否也可以创建一个核外 DataArray,并使用 xarray 将其逐块写入 NetCDF4 文件?
例如,当维度更大时,我希望能够以核外方式执行此操作,因此我无法将整个数组存储在内存中:
num_steps = 20
num_times = 100
#Create DataArray
d = xr.DataArray(np.zeros([num_steps, num_times], np.float32),
{'Step': np.arange(num_steps),
'Time': np.arange(num_times)},
('Step', 'Time'))
#Computatation
for i in range(num_steps):
d[i, :] = i
#Write to file
d.to_netcdf('test.nc')
Run Code Online (Sandbox Code Playgroud)
所以我不想在内存中创建整个 NumPy 数组,我希望计算和写入文件阶段一次完成一个块(在本例中在 Step 维度上分块)。
更新:似乎(来自@jhamman 的回答)可能无法使用 xarray 实现我上面的示例。我的主要兴趣是加深对 xarray 的核外计算的理解,所以我没有要问的特定计算,但是,由于有人要求我提供一个更复杂的示例,因此我有一个潜在的应用程序有是:
for i in range(num_steps):
u[:] = f(u)
s[:] = g(s)
d[i, :] = u[:] * s[:]
Run Code Online (Sandbox Code Playgroud)
其中u和s是维时间xr.DataArrays,和f和g是PDE求解器仅依赖来自前面步骤的输入阵列上。假设有 1000 步,但 Time 维度太大,我只能在内存中存储一两个,因此d …