Xarray:将多个 CSV 文件加载到数据集中
Xarray: Loading several CSV files into a dataset
我有几个要加载到 xarray 数据集中的逗号分隔数据文件。每个文件中的每一行代表固定网格中字段的不同空间值,每个文件代表不同的时间点。网格间距是固定的,不随时间变化。网格间距不均匀。最终目标是计算 max_{x, y} { std_t[ value(x, y, t) * sqrt(y **2 + x ** 2)] }
,其中 sqrt 是平方根,std_t
是相对于时间的标准差,max_{x, y}
是所有 space 的最大值。
我在加载数据时遇到问题。我不清楚应该如何将多个 CSV 文件加载到 xarray 数据集中。有一个 open_mfdataset
函数,它是为将多个数据文件加载到数据集中而设计的,但似乎需要 hdf5 或 netcdf 文件。
似乎无法将常规 CSV 文件加载到 xarray 数据集中,因此有必要对数据进行预处理。在我的示例中,我决定预先将 csv 文件预处理为 hdf5 文件,以利用 h5netcdf
引擎。这对我来说似乎是一个特定于 hdf5 的问题。
下面是我迄今为止加载数据的最佳尝试。不幸的是,它会产生一个空的 xarray 数据集。我在 open_mfdataset
函数中尝试了几个选项,下面的代码只是多次尝试使用该函数的一种实现。
我如何将这些 csv 文件加载到单个 xarray 数据集中,以设置自己以找到感兴趣值的 space 时间标准偏差的最大值?
import xarray as xr
import numpy as np
import pandas as pd
'''
Create example files
- Each file contains a spatial-dependent value, f(x, y)
- Each file represents a different point in time, f(x, y, t)
'''
for ii in range(7):
# create csv file
fl = open('exampleFile%i.dat' % ii, 'w')
fl.write('time x1 x2 value\n')
for xx in range(10):
for yy in range(10):
fl.write('%i %i %i %i\n' %
(ii, xx, yy, (xx - yy) * np.exp(ii)))
fl.close()
# convert csv to hdf5
dat = pd.read_csv('exampleFile%i.dat' % ii)
dat.to_hdf('exampleFile%i.hdf5' % ii, 'data', mode='w')
'''
Read all files into xarray dataframe
(the ultimate goal is to find the
maximum across time of
the standard deviation across space
of the "value" column)
'''
result = xr.open_mfdataset('exampleFile*.hdf5', engine='h5netcdf', combine='nested')
... 当我 运行 代码时,result
变量似乎不包含所需数据:
In: result
Out:
<xarray.Dataset>
Dimensions: ()
Data variables:
*empty*
Attributes:
PYTABLES_FORMAT_VERSION: 2.1
TITLE: Empty(dtype=dtype('S1'))
VERSION: 1.0
编辑
发布了一个假设统一 spaced 空间网格的答案。这是一个稍微修改过的例子,它不假设空间点的均匀 spaced 网格。
该示例还假设了三个空间维度。这更符合我的实际问题,我意识到这可能是这个简单示例中的一个重要细节。
import xarray as xr
import numpy as np
import pandas as pd
'''
Create example files
- Each file contains a spatial-dependent value, f(x, y)
- Each file represents a different point in time, f(x, y, t)
'''
for ii in range(7):
# create csv file
fl = open('exampleFile%i.dat' % ii, 'w')
fl.write('time x y z value\n')
for xx in range(10):
for yy in range(int(10 + xx // 2)):
for zz in range(int(10 + xx //3 + yy // 3)):
fl.write('%i %f %f %f %f\n' %
(ii, xx * np.exp(- 1 * yy * zz) , yy * np.exp(xx - zz), zz * np.exp(xx * yy), (xx - yy) * np.exp(ii)))
fl.close()
# convert csv to hdf5
dat = pd.read_csv('exampleFile%i.dat' % ii)
dat.to_hdf('exampleFile%i.hdf5' % ii, 'data', mode='w')
'''
Read all files into xarray dataframe
(the ultimate goal is to find the
maximum across time of
the standard deviation across space
of the "value" column)
'''
result = xr.open_mfdataset('exampleFile*.hdf5', engine='h5netcdf', combine='nested')
我的方法是创建一个解析函数,将 CSV 转换为 xarray.Dataset
s。
通过这种方式,您可以使用 xarray.concat
将它们组合成最终数据集,您可以在该数据集上执行计算。
以下适用于您的示例数据:
from glob import glob
def csv2xr(csv, sep=" "):
df = pd.read_csv(csv, sep)
x = df.x1.unique()
y = df.x2.unique()
pix = df.value.values.reshape(1, x.size, y.size)
ds = xr.Dataset({
"value": xr.DataArray(
pix,
dims=['time', 'x', 'y'],
coords={"time": df.time.unique(), "x": x, "y": y})
})
return ds
csvs = glob("*dat")
ds_full = xr.concat([csv2xr(x) for x in csvs], dim="time")
print(ds_full)
#<xarray.Dataset>
# Dimensions: (time: 7, x: 10, y: 10)
# Coordinates:
# * time (time) int64 4 3 2 0 1 6 5
# * x (x) int64 0 1 2 3 4 5 6 7 8 9
# * y (y) int64 0 1 2 3 4 5 6 7 8 9
# Data variables:
# value (time, x, y) int64 0 -54 -109 -163 -218 -272 ... 593 445 296 148 0
然后得到 std
超过 time
的最大值:
ds_full.std("time").max()
希望我理解你的问题。看看这是否适合你。
定义 read_csv
的关键参数时,请注意使用 delim_whitespace=True
比 sep=" "
更好。如果某处有双空格,这将避免考虑双列。
我正在传递给 read_csv
time
、x
、y
和 z
都是坐标,我正在将它们转换为 xarray
.它会自动构建您的非结构化数据并用 NaN
填充空洞。然后我通过 time
.
将所有 xarray
对象连接成一个对象
from glob import glob
fnames = glob('*.dat')
fnames.sort()
kw = dict(delim_whitespace=True,index_col=['time','x','y','z'])
ds = xr.concat([pd.read_csv(fname,**kw).to_xarray() for fname in fnames],'time')
最终结果是一个 xarray
对象,如下所示:
现在你可以用这个对象做任何事情了。
ds.max(['x','y','z']).std('time')
将 return 所有变量的空间最大值的时间标准偏差(在这种情况下它只是 value
列)。请注意,有时您可能必须传递 skipna=True
以避免从分析中得到 NaN
输出。
请告诉我它可以解决您的问题,如果它不能解决您在数据方面遇到的某些特定问题,我很乐意对其进行调整。
我有几个要加载到 xarray 数据集中的逗号分隔数据文件。每个文件中的每一行代表固定网格中字段的不同空间值,每个文件代表不同的时间点。网格间距是固定的,不随时间变化。网格间距不均匀。最终目标是计算 max_{x, y} { std_t[ value(x, y, t) * sqrt(y **2 + x ** 2)] }
,其中 sqrt 是平方根,std_t
是相对于时间的标准差,max_{x, y}
是所有 space 的最大值。
我在加载数据时遇到问题。我不清楚应该如何将多个 CSV 文件加载到 xarray 数据集中。有一个 open_mfdataset
函数,它是为将多个数据文件加载到数据集中而设计的,但似乎需要 hdf5 或 netcdf 文件。
似乎无法将常规 CSV 文件加载到 xarray 数据集中,因此有必要对数据进行预处理。在我的示例中,我决定预先将 csv 文件预处理为 hdf5 文件,以利用 h5netcdf
引擎。这对我来说似乎是一个特定于 hdf5 的问题。
下面是我迄今为止加载数据的最佳尝试。不幸的是,它会产生一个空的 xarray 数据集。我在 open_mfdataset
函数中尝试了几个选项,下面的代码只是多次尝试使用该函数的一种实现。
我如何将这些 csv 文件加载到单个 xarray 数据集中,以设置自己以找到感兴趣值的 space 时间标准偏差的最大值?
import xarray as xr
import numpy as np
import pandas as pd
'''
Create example files
- Each file contains a spatial-dependent value, f(x, y)
- Each file represents a different point in time, f(x, y, t)
'''
for ii in range(7):
# create csv file
fl = open('exampleFile%i.dat' % ii, 'w')
fl.write('time x1 x2 value\n')
for xx in range(10):
for yy in range(10):
fl.write('%i %i %i %i\n' %
(ii, xx, yy, (xx - yy) * np.exp(ii)))
fl.close()
# convert csv to hdf5
dat = pd.read_csv('exampleFile%i.dat' % ii)
dat.to_hdf('exampleFile%i.hdf5' % ii, 'data', mode='w')
'''
Read all files into xarray dataframe
(the ultimate goal is to find the
maximum across time of
the standard deviation across space
of the "value" column)
'''
result = xr.open_mfdataset('exampleFile*.hdf5', engine='h5netcdf', combine='nested')
... 当我 运行 代码时,result
变量似乎不包含所需数据:
In: result
Out:
<xarray.Dataset>
Dimensions: ()
Data variables:
*empty*
Attributes:
PYTABLES_FORMAT_VERSION: 2.1
TITLE: Empty(dtype=dtype('S1'))
VERSION: 1.0
编辑
发布了一个假设统一 spaced 空间网格的答案。这是一个稍微修改过的例子,它不假设空间点的均匀 spaced 网格。
该示例还假设了三个空间维度。这更符合我的实际问题,我意识到这可能是这个简单示例中的一个重要细节。
import xarray as xr
import numpy as np
import pandas as pd
'''
Create example files
- Each file contains a spatial-dependent value, f(x, y)
- Each file represents a different point in time, f(x, y, t)
'''
for ii in range(7):
# create csv file
fl = open('exampleFile%i.dat' % ii, 'w')
fl.write('time x y z value\n')
for xx in range(10):
for yy in range(int(10 + xx // 2)):
for zz in range(int(10 + xx //3 + yy // 3)):
fl.write('%i %f %f %f %f\n' %
(ii, xx * np.exp(- 1 * yy * zz) , yy * np.exp(xx - zz), zz * np.exp(xx * yy), (xx - yy) * np.exp(ii)))
fl.close()
# convert csv to hdf5
dat = pd.read_csv('exampleFile%i.dat' % ii)
dat.to_hdf('exampleFile%i.hdf5' % ii, 'data', mode='w')
'''
Read all files into xarray dataframe
(the ultimate goal is to find the
maximum across time of
the standard deviation across space
of the "value" column)
'''
result = xr.open_mfdataset('exampleFile*.hdf5', engine='h5netcdf', combine='nested')
我的方法是创建一个解析函数,将 CSV 转换为 xarray.Dataset
s。
通过这种方式,您可以使用 xarray.concat
将它们组合成最终数据集,您可以在该数据集上执行计算。
以下适用于您的示例数据:
from glob import glob
def csv2xr(csv, sep=" "):
df = pd.read_csv(csv, sep)
x = df.x1.unique()
y = df.x2.unique()
pix = df.value.values.reshape(1, x.size, y.size)
ds = xr.Dataset({
"value": xr.DataArray(
pix,
dims=['time', 'x', 'y'],
coords={"time": df.time.unique(), "x": x, "y": y})
})
return ds
csvs = glob("*dat")
ds_full = xr.concat([csv2xr(x) for x in csvs], dim="time")
print(ds_full)
#<xarray.Dataset>
# Dimensions: (time: 7, x: 10, y: 10)
# Coordinates:
# * time (time) int64 4 3 2 0 1 6 5
# * x (x) int64 0 1 2 3 4 5 6 7 8 9
# * y (y) int64 0 1 2 3 4 5 6 7 8 9
# Data variables:
# value (time, x, y) int64 0 -54 -109 -163 -218 -272 ... 593 445 296 148 0
然后得到 std
超过 time
的最大值:
ds_full.std("time").max()
希望我理解你的问题。看看这是否适合你。
定义 read_csv
的关键参数时,请注意使用 delim_whitespace=True
比 sep=" "
更好。如果某处有双空格,这将避免考虑双列。
我正在传递给 read_csv
time
、x
、y
和 z
都是坐标,我正在将它们转换为 xarray
.它会自动构建您的非结构化数据并用 NaN
填充空洞。然后我通过 time
.
xarray
对象连接成一个对象
from glob import glob
fnames = glob('*.dat')
fnames.sort()
kw = dict(delim_whitespace=True,index_col=['time','x','y','z'])
ds = xr.concat([pd.read_csv(fname,**kw).to_xarray() for fname in fnames],'time')
最终结果是一个 xarray
对象,如下所示:
现在你可以用这个对象做任何事情了。
ds.max(['x','y','z']).std('time')
将 return 所有变量的空间最大值的时间标准偏差(在这种情况下它只是 value
列)。请注意,有时您可能必须传递 skipna=True
以避免从分析中得到 NaN
输出。
请告诉我它可以解决您的问题,如果它不能解决您在数据方面遇到的某些特定问题,我很乐意对其进行调整。