xarray expand_dim 添加更高级别的维度
xarray expand_dim to add higher level dimension
我正在尝试连接一个数据数组列表,然后添加一个维度,以便标记连接的每个数据数组。我认为这是 expand_dims 的一个用例,但在尝试了 SO 的各种解决方案后,我被卡住了。我想我缺少一些关于 xarray 的基本知识。
这些似乎是最接近的:
Add a 'time' dimension to xarray Dataset and assign coordinates from another Dataset to it
我使用 pandas 数据帧从文件名编译元数据,然后分组并遍历组以创建数据集,使用 skimage.io.ImageCollection 将多个图像文件加载到 nparray,并最终创建 xarray 对象
独立示例
设置
#%% load libraries
from itertools import product
from PIL import Image
import numpy as np
import pandas as pd
import xarray as xr
import glob
from skimage import io
import re
#%% Synthetic data generator
ext = 'png'
delim = '_'
datadir = os.path.join('data','syn')
os.makedirs(datadir, exist_ok=True)
cartag = ['A1', 'A2']
date = ['2020-05-31', '2020-06-01', '2020-06-02']
frame = ['Fp', 'Fmp']
parameter = ['FvFm','t40', 't60']
list_vals = [cartag, date, frame, parameter]
mesh = list(product(*list_vals))
mesh = np.array(mesh)
for entry in mesh:
print(entry)
img = np.random.random_sample((8, 8))*255
img = img.astype('uint8')
fn = delim.join(entry)+'.png'
pimg = Image.fromarray(img)
pimg.save(os.path.join(datadir,fn))
#%% import synthetic images
fns = [
fn for fn in glob.glob(pathname=os.path.join(datadir, '*%s' % ext))
]
flist = list()
for fullfn in fns:
fn = os.path.basename(fullfn)
fn,_ = os.path.splitext(fn)
f = fn.split(delim)
f.append(fullfn)
flist.append(f)
fdf = pd.DataFrame(flist,
columns=[
'plantbarcode', 'timestamp',
'frame','parameter', 'filename'
])
fdf=fdf.sort_values(['timestamp','plantbarcode','parameter','frame'])
函数定义
#%%
def get_tind_seconds(parameter):
tind = re.search("\d+", parameter)
if tind is not None:
tind = int(tind.group())
elif parameter == 'FvFm':
tind = 0
else:
raise ValueError("the parameter '%s' is not supported" % parameter)
return (tind)
xarray 部分
dfgrps = fdf.groupby(['plantbarcode', 'timestamp', 'parameter'])
ds = list()
for grp, grpdf in dfgrps:
# print(grpdf.parameter.unique())
parameter = grpdf.parameter.unique()[0]
tind = get_tind_seconds(
parameter
) #tind is an integer representing seconds since start of experiment
# print(tind)
filenames = grpdf.filename.to_list()
imgcol = io.ImageCollection(filenames)
imgstack = imgcol.concatenate() #imgstack is now 2x8x8 ndarray
indf = grpdf.frame #the 2 dim are frames Fp and Fmp
# print(indf)
arr = xr.DataArray(name=parameter,
data=imgstack,
dims=('frame', 'y', 'x'),
coords={
# 'frame': indf,
'parameter': [parameter,parameter]
# 'tind_s': [tind,tind]
},
attrs={
'jobdate': grpdf.timestamp.unique()[0],
'plantbarcode': grpdf.plantbarcode.unique()[0]
})
# arr = arr.expand_dims(
# dims={'tind_s': tind}
# ) #<- somehow I need to label each dataarray with another dimension assigning it the dim/coord `tind`
ds.append(arr)
dstest = xr.concat(ds, dim='parameter')
目标是每天都有一个不同的文件,plantbarcode。所以在这种情况下有 4 个文件。 其中图像可以通过参数和帧进行索引。 tind_s 通常用于绘制每个参数的每个图像的摘要统计信息,所以我也想制作 dim/coord - 我不确定何时使用哪个。看起来 dim 必须与传入的数据相匹配,因此在本例中为 2 帧 x 8x8 像素。
原创
我使用 pandas 数据框从文件名编译元数据(这里是前几个条目)
frameid plantbarcode experiment datetime jobdate cameralabel filename frame parameter
4 5 A1 doi 2020-05-31 21:01:55 2020-06-01 PSII0 data/psII/A1-doi-20200531T210155-PSII0-5.png Fp FvFm
5 6 A1 doi 2020-05-31 21:01:55 2020-06-01 PSII0 data/psII/A1-doi-20200531T210155-PSII0-6.png Fmp FvFm
6 7 A1 doi 2020-05-31 21:01:55 2020-06-01 PSII0 data/psII/A1-doi-20200531T210155-PSII0-7.png Fp t40_ALon
7 8 A1 doi 2020-05-31 21:01:55 2020-06-01 PSII0 data/psII/A1-doi-20200531T210155-PSII0-8.png Fmp t40_ALon
8 9 A1 doi 2020-05-31 21:01:55 2020-06-01 PSII0 data/psII/A1-doi-20200531T210155-PSII0-9.png Fp t60_ALon
9 10 A1 doi 2020-05-31 21:01:55 2020-06-01 PSII0 data/psII/A1-doi-20200531T210155-PSII0-10.png Fmp t60_ALon
...
然后分组迭代创建数据集,使用skimage.io.ImageCollection加载多个图像文件到nparray,最终创建xarray对象
import os
import cppcpyutils as cppc
import re
from skimage import io
import xarray as xr
import numpy as np
import pandas as pd
delimiter = "(.{2})-(.+)-(\d{8}T\d{6})-(.+)-(\d+)"
filedf = cppc.io.import_snapshots('data/psII', camera='psII', delimiter=delimiter)
filedf = filedf.reset_index().set_index('frameid')
pimframes_map = pd.read_csv('data/pimframes_map.csv',index_col = 'frameid')
filedf = filedf.join(pimframes_map, on = 'frameid').reset_index().query('frameid not in [3,4,5,6]')
dfgrps = filedf.groupby(['experiment', 'plantbarcode', 'jobdate', 'datetime', 'parameter'])
ds=list()
for grp, grpdf in dfgrps:
# print(grpdf.parameter.unique())
parameter = grpdf.parameter.unique()[0]
tind = get_tind_seconds(parameter) #tind is an integer representing seconds since start of experiment
# print(tind)
filenames = grpdf.filename.to_list()
imgcol = io.ImageCollection(filenames)
imgstack = imgcol.concatenate() #imgstack is now 2x640x480 ndarray
indf = grpdf.frame #the 2 dim are frames Fp and Fmp
# print(indf)
arr = xr.DataArray(name=parameter,
data=imgstack,
dims=('induction frame','y', 'x'),
coords={'induction frame': indf},
attrs={'plantbarcode': grpdf.plantbarcode.unique()[0],
'jobdate': grpdf.jobdate.unique()[0]})
arr = arr.expand_dims(dims = {'tind_s': tind}) #<- somehow I need to label each dataarray with another dimension assigning it the dim/coord `tind`
ds.append(arr)
expand_dims 行导致 ValueError: dimensions ('dims',) must have the same length as the number of data dimensions, ndim=0
如果我尝试遵循第二个 SO 我 link 在上面我提供 'tind_s' 作为坐标的地方它抱怨相对于 dims 太多了。
ValueError: coordinate tind_s has dimensions ('tind_s',), but these are not a subset of the DataArray dimensions ('induction frame', 'y', 'x')
然后我想连接在一起 tind_s 是一个坐标
dstest=xr.concat(ds[0:4], dim = 'tind_s')
再次尝试
我确实发现我可以在 imgstack
上使用 np.expand_dims()
,然后指定额外的 dim 和 coord,但它会生成一个 nan 数组。此外,xr.concat() 的结果是数据数组而不是数据集,因此无法保存(?)。 xarray 中有直接的方法可以做到这一点吗?
我还将属性转换为 dims
dfgrps = filedf.groupby(
['experiment', 'plantbarcode', 'jobdate', 'datetime', 'parameter'])
dalist = list()
for grp, grpdf in dfgrps:
print(grpdf.parameter.unique())
parameter = grpdf.parameter.unique()[0]
tind = get_tind_seconds(parameter)
# print(tind)
print(grpdf.plantbarcode.unique())
print(grpdf.jobdate.unique()[0])
filenames = grpdf.filename.to_list()
imgcol = io.ImageCollection(filenames)
imgstack = imgcol.concatenate()
imgstack = np.expand_dims(imgstack, axis=0)
imgstack = np.expand_dims(imgstack, axis=0)
imgstack = np.expand_dims(imgstack, axis=0)
indf = grpdf.frame #xr.Variable('induction frame', grpdf.frame)
# tind = xr.Variable('tind', [tind])
# print(indf)
arr = xr.DataArray(data=imgstack,
dims=('jobdate','plantbarcode', 'tind_s', 'induction frame', 'y',
'x'),
coords={
'plantbarcode': grpdf.plantbarcode.unique(),
'tind_s': [tind],
'induction frame': indf,
'jobdate': grpdf.jobdate.unique()}
)
dalist.append(arr)
ds = xr.concat(dalist, dim='jobdate')
for 循环后:print(arr)
<xarray.DataArray (jobdate: 1, plantbarcode: 1, tind_s: 1, induction frame: 2, y: 640, x: 480)>
array([[[[[[0, 0, 0, ..., 0, 0, 0],
[1, 1, 0, ..., 0, 0, 0],
[0, 0, 2, ..., 0, 0, 0],
...,
[1, 0, 0, ..., 0, 1, 0],
[1, 0, 0, ..., 0, 0, 1],
[1, 0, 0, ..., 1, 1, 0]],
[[0, 0, 0, ..., 0, 1, 1],
[2, 2, 0, ..., 0, 0, 1],
[2, 1, 1, ..., 0, 0, 0],
...,
[0, 1, 0, ..., 1, 0, 1],
[1, 0, 0, ..., 0, 1, 1],
[0, 0, 0, ..., 0, 0, 0]]]]]], dtype=uint8)
Coordinates:
* plantbarcode (plantbarcode) object 'A2'
* tind_s (tind_s) int64 60
* induction frame (induction frame) object 'Fp' 'Fmp'
* jobdate (jobdate) datetime64[ns] 2020-06-03
Dimensions without coordinates: y, x
和print(ds)
print(ds)
<xarray.DataArray (jobdate: 18, plantbarcode: 2, tind_s: 3, induction frame: 2, y: 640, x: 480)>
array([[[[[[ 0., 0., 0., ..., 0., 0., 1.],
[ 0., 0., 1., ..., 2., 0., 0.],
[ 0., 0., 0., ..., 0., 0., 0.],
...,
[ 1., 0., 0., ..., 7., 0., 0.],
[ 0., 2., 4., ..., 0., 0., 4.],
[ 0., 1., 0., ..., 1., 0., 0.]],
[[ 0., 1., 0., ..., 0., 1., 0.],
[ 0., 0., 1., ..., 1., 2., 1.],
[ 0., 1., 1., ..., 1., 0., 0.],
...,
[ 1., 2., 2., ..., 0., 1., 1.],
[ 1., 1., 1., ..., 0., 1., 0.],
[ 0., 0., 2., ..., 0., 0., 1.]]],
[[[nan, nan, nan, ..., nan, nan, nan],
[nan, nan, nan, ..., nan, nan, nan],
[nan, nan, nan, ..., nan, nan, nan],
...
[nan, nan, nan, ..., nan, nan, nan],
[nan, nan, nan, ..., nan, nan, nan],
[nan, nan, nan, ..., nan, nan, nan]]],
[[[ 0., 0., 0., ..., 0., 0., 0.],
[ 1., 1., 0., ..., 0., 0., 0.],
[ 0., 0., 2., ..., 0., 0., 0.],
...,
[ 1., 0., 0., ..., 0., 1., 0.],
[ 1., 0., 0., ..., 0., 0., 1.],
[ 1., 0., 0., ..., 1., 1., 0.]],
[[ 0., 0., 0., ..., 0., 1., 1.],
[ 2., 2., 0., ..., 0., 0., 1.],
[ 2., 1., 1., ..., 0., 0., 0.],
...,
[ 0., 1., 0., ..., 1., 0., 1.],
[ 1., 0., 0., ..., 0., 1., 1.],
[ 0., 0., 0., ..., 0., 0., 0.]]]]]])
Coordinates:
* plantbarcode (plantbarcode) object 'A1' 'A2'
* tind_s (tind_s) int64 0 40 60
* induction frame (induction frame) object 'Fp' 'Fmp'
* jobdate (jobdate) datetime64[ns] 2020-06-01 ... 2020-06-03
Dimensions without coordinates: y, x
我不明白nan数组是从哪里来的。对我来说,无论在 concat 中使用什么 dim,这对每个条目(在本例中为 18 个文件)都有一个坐标值,即使它们不是唯一的,但其他 dims 仅显示为唯一值,这对我来说也很奇怪。
如果有人愿意下载一个小数据集,这里是一个 link(很抱歉反对 link 中的建议,我会尝试提出一个可以生成的合成数据集即时)
我在 xarray 邮件列表上看到了你的问题。很难调试这个问题,因为它很复杂并且取决于您的数据。如果您可以稍微简化它并使用合成数据而不是您的数据文件,那就太好了——请参阅 https://matthewrocklin.com/blog/work/2018/02/28/minimal-bug-reports 以获取有关这方面的建议。
如果您分享 print(arr)
的输出,这也会很有帮助,这样我们就可以了解您的 DataArrays 的内容和结构。
您的原始代码在 arr.expand_dims(dims={'tind_s': tind})
中包含一个微妙的错误(拼写错误):我猜您想要 dim
而不是 dims
,后者被 xarray 解释为新的维度标签(参见 doc)。此外,tind
在这里用作沿新维度创建的元素数,这可能也不是您想要的。
您的其他尝试(即在创建 DataArray
之前扩展数据维度)是 IMO 更好的方法,但它可以进一步改进。鉴于您在同一串联维度上有多个标签,我建议您创建一个多索引并将其分配给串联维度,即
import numpy as np
import pandas as pd
import xarray as xr
da_list = []
props = []
prop_names = ['experiment', 'plantbarcode', 'tind']
for i in range(10):
tind = i
indf = ['Fp', 'Fmp']
data = np.ones((2, 640, 480)) * i
da = xr.DataArray(
data=data[None, ...],
dims=('props', 'frame', 'y', 'x'),
coords={'frame': indf}
)
props.append((f'experiment{i}', i*2, i))
da_list.append(da)
prop_idx = pd.MultiIndex.from_tuples(props, names=prop_names)
da_concat = xr.concat(da_list, 'props')
da_concat.coords['props'] = prop_idx
给出:
<xarray.DataArray (props: 10, frame: 2, y: 640, x: 480)>
array([[[[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
...,
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.]],
[[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
...,
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.]]],
[[[1., 1., 1., ..., 1., 1., 1.],
[1., 1., 1., ..., 1., 1., 1.],
[1., 1., 1., ..., 1., 1., 1.],
...
[8., 8., 8., ..., 8., 8., 8.],
[8., 8., 8., ..., 8., 8., 8.],
[8., 8., 8., ..., 8., 8., 8.]]],
[[[9., 9., 9., ..., 9., 9., 9.],
[9., 9., 9., ..., 9., 9., 9.],
[9., 9., 9., ..., 9., 9., 9.],
...,
[9., 9., 9., ..., 9., 9., 9.],
[9., 9., 9., ..., 9., 9., 9.],
[9., 9., 9., ..., 9., 9., 9.]],
[[9., 9., 9., ..., 9., 9., 9.],
[9., 9., 9., ..., 9., 9., 9.],
[9., 9., 9., ..., 9., 9., 9.],
...,
[9., 9., 9., ..., 9., 9., 9.],
[9., 9., 9., ..., 9., 9., 9.],
[9., 9., 9., ..., 9., 9., 9.]]]])
Coordinates:
* frame (frame) <U3 'Fp' 'Fmp'
* props (props) MultiIndex
- experiment (props) object 'experiment0' 'experiment1' ... 'experiment9'
- plantbarcode (props) int64 0 2 4 6 8 10 12 14 16 18
- tind (props) int64 0 1 2 3 4 5 6 7 8 9
Dimensions without coordinates: y, x
我正在尝试连接一个数据数组列表,然后添加一个维度,以便标记连接的每个数据数组。我认为这是 expand_dims 的一个用例,但在尝试了 SO 的各种解决方案后,我被卡住了。我想我缺少一些关于 xarray 的基本知识。 这些似乎是最接近的:
Add a 'time' dimension to xarray Dataset and assign coordinates from another Dataset to it
我使用 pandas 数据帧从文件名编译元数据,然后分组并遍历组以创建数据集,使用 skimage.io.ImageCollection 将多个图像文件加载到 nparray,并最终创建 xarray 对象
独立示例
设置
#%% load libraries
from itertools import product
from PIL import Image
import numpy as np
import pandas as pd
import xarray as xr
import glob
from skimage import io
import re
#%% Synthetic data generator
ext = 'png'
delim = '_'
datadir = os.path.join('data','syn')
os.makedirs(datadir, exist_ok=True)
cartag = ['A1', 'A2']
date = ['2020-05-31', '2020-06-01', '2020-06-02']
frame = ['Fp', 'Fmp']
parameter = ['FvFm','t40', 't60']
list_vals = [cartag, date, frame, parameter]
mesh = list(product(*list_vals))
mesh = np.array(mesh)
for entry in mesh:
print(entry)
img = np.random.random_sample((8, 8))*255
img = img.astype('uint8')
fn = delim.join(entry)+'.png'
pimg = Image.fromarray(img)
pimg.save(os.path.join(datadir,fn))
#%% import synthetic images
fns = [
fn for fn in glob.glob(pathname=os.path.join(datadir, '*%s' % ext))
]
flist = list()
for fullfn in fns:
fn = os.path.basename(fullfn)
fn,_ = os.path.splitext(fn)
f = fn.split(delim)
f.append(fullfn)
flist.append(f)
fdf = pd.DataFrame(flist,
columns=[
'plantbarcode', 'timestamp',
'frame','parameter', 'filename'
])
fdf=fdf.sort_values(['timestamp','plantbarcode','parameter','frame'])
函数定义
#%%
def get_tind_seconds(parameter):
tind = re.search("\d+", parameter)
if tind is not None:
tind = int(tind.group())
elif parameter == 'FvFm':
tind = 0
else:
raise ValueError("the parameter '%s' is not supported" % parameter)
return (tind)
xarray 部分
dfgrps = fdf.groupby(['plantbarcode', 'timestamp', 'parameter'])
ds = list()
for grp, grpdf in dfgrps:
# print(grpdf.parameter.unique())
parameter = grpdf.parameter.unique()[0]
tind = get_tind_seconds(
parameter
) #tind is an integer representing seconds since start of experiment
# print(tind)
filenames = grpdf.filename.to_list()
imgcol = io.ImageCollection(filenames)
imgstack = imgcol.concatenate() #imgstack is now 2x8x8 ndarray
indf = grpdf.frame #the 2 dim are frames Fp and Fmp
# print(indf)
arr = xr.DataArray(name=parameter,
data=imgstack,
dims=('frame', 'y', 'x'),
coords={
# 'frame': indf,
'parameter': [parameter,parameter]
# 'tind_s': [tind,tind]
},
attrs={
'jobdate': grpdf.timestamp.unique()[0],
'plantbarcode': grpdf.plantbarcode.unique()[0]
})
# arr = arr.expand_dims(
# dims={'tind_s': tind}
# ) #<- somehow I need to label each dataarray with another dimension assigning it the dim/coord `tind`
ds.append(arr)
dstest = xr.concat(ds, dim='parameter')
目标是每天都有一个不同的文件,plantbarcode。所以在这种情况下有 4 个文件。 其中图像可以通过参数和帧进行索引。 tind_s 通常用于绘制每个参数的每个图像的摘要统计信息,所以我也想制作 dim/coord - 我不确定何时使用哪个。看起来 dim 必须与传入的数据相匹配,因此在本例中为 2 帧 x 8x8 像素。
原创
我使用 pandas 数据框从文件名编译元数据(这里是前几个条目)
frameid plantbarcode experiment datetime jobdate cameralabel filename frame parameter
4 5 A1 doi 2020-05-31 21:01:55 2020-06-01 PSII0 data/psII/A1-doi-20200531T210155-PSII0-5.png Fp FvFm
5 6 A1 doi 2020-05-31 21:01:55 2020-06-01 PSII0 data/psII/A1-doi-20200531T210155-PSII0-6.png Fmp FvFm
6 7 A1 doi 2020-05-31 21:01:55 2020-06-01 PSII0 data/psII/A1-doi-20200531T210155-PSII0-7.png Fp t40_ALon
7 8 A1 doi 2020-05-31 21:01:55 2020-06-01 PSII0 data/psII/A1-doi-20200531T210155-PSII0-8.png Fmp t40_ALon
8 9 A1 doi 2020-05-31 21:01:55 2020-06-01 PSII0 data/psII/A1-doi-20200531T210155-PSII0-9.png Fp t60_ALon
9 10 A1 doi 2020-05-31 21:01:55 2020-06-01 PSII0 data/psII/A1-doi-20200531T210155-PSII0-10.png Fmp t60_ALon
...
然后分组迭代创建数据集,使用skimage.io.ImageCollection加载多个图像文件到nparray,最终创建xarray对象
import os
import cppcpyutils as cppc
import re
from skimage import io
import xarray as xr
import numpy as np
import pandas as pd
delimiter = "(.{2})-(.+)-(\d{8}T\d{6})-(.+)-(\d+)"
filedf = cppc.io.import_snapshots('data/psII', camera='psII', delimiter=delimiter)
filedf = filedf.reset_index().set_index('frameid')
pimframes_map = pd.read_csv('data/pimframes_map.csv',index_col = 'frameid')
filedf = filedf.join(pimframes_map, on = 'frameid').reset_index().query('frameid not in [3,4,5,6]')
dfgrps = filedf.groupby(['experiment', 'plantbarcode', 'jobdate', 'datetime', 'parameter'])
ds=list()
for grp, grpdf in dfgrps:
# print(grpdf.parameter.unique())
parameter = grpdf.parameter.unique()[0]
tind = get_tind_seconds(parameter) #tind is an integer representing seconds since start of experiment
# print(tind)
filenames = grpdf.filename.to_list()
imgcol = io.ImageCollection(filenames)
imgstack = imgcol.concatenate() #imgstack is now 2x640x480 ndarray
indf = grpdf.frame #the 2 dim are frames Fp and Fmp
# print(indf)
arr = xr.DataArray(name=parameter,
data=imgstack,
dims=('induction frame','y', 'x'),
coords={'induction frame': indf},
attrs={'plantbarcode': grpdf.plantbarcode.unique()[0],
'jobdate': grpdf.jobdate.unique()[0]})
arr = arr.expand_dims(dims = {'tind_s': tind}) #<- somehow I need to label each dataarray with another dimension assigning it the dim/coord `tind`
ds.append(arr)
expand_dims 行导致 ValueError: dimensions ('dims',) must have the same length as the number of data dimensions, ndim=0
如果我尝试遵循第二个 SO 我 link 在上面我提供 'tind_s' 作为坐标的地方它抱怨相对于 dims 太多了。
ValueError: coordinate tind_s has dimensions ('tind_s',), but these are not a subset of the DataArray dimensions ('induction frame', 'y', 'x')
然后我想连接在一起 tind_s 是一个坐标
dstest=xr.concat(ds[0:4], dim = 'tind_s')
再次尝试
我确实发现我可以在 imgstack
上使用 np.expand_dims()
,然后指定额外的 dim 和 coord,但它会生成一个 nan 数组。此外,xr.concat() 的结果是数据数组而不是数据集,因此无法保存(?)。 xarray 中有直接的方法可以做到这一点吗?
我还将属性转换为 dims
dfgrps = filedf.groupby(
['experiment', 'plantbarcode', 'jobdate', 'datetime', 'parameter'])
dalist = list()
for grp, grpdf in dfgrps:
print(grpdf.parameter.unique())
parameter = grpdf.parameter.unique()[0]
tind = get_tind_seconds(parameter)
# print(tind)
print(grpdf.plantbarcode.unique())
print(grpdf.jobdate.unique()[0])
filenames = grpdf.filename.to_list()
imgcol = io.ImageCollection(filenames)
imgstack = imgcol.concatenate()
imgstack = np.expand_dims(imgstack, axis=0)
imgstack = np.expand_dims(imgstack, axis=0)
imgstack = np.expand_dims(imgstack, axis=0)
indf = grpdf.frame #xr.Variable('induction frame', grpdf.frame)
# tind = xr.Variable('tind', [tind])
# print(indf)
arr = xr.DataArray(data=imgstack,
dims=('jobdate','plantbarcode', 'tind_s', 'induction frame', 'y',
'x'),
coords={
'plantbarcode': grpdf.plantbarcode.unique(),
'tind_s': [tind],
'induction frame': indf,
'jobdate': grpdf.jobdate.unique()}
)
dalist.append(arr)
ds = xr.concat(dalist, dim='jobdate')
for 循环后:print(arr)
<xarray.DataArray (jobdate: 1, plantbarcode: 1, tind_s: 1, induction frame: 2, y: 640, x: 480)>
array([[[[[[0, 0, 0, ..., 0, 0, 0],
[1, 1, 0, ..., 0, 0, 0],
[0, 0, 2, ..., 0, 0, 0],
...,
[1, 0, 0, ..., 0, 1, 0],
[1, 0, 0, ..., 0, 0, 1],
[1, 0, 0, ..., 1, 1, 0]],
[[0, 0, 0, ..., 0, 1, 1],
[2, 2, 0, ..., 0, 0, 1],
[2, 1, 1, ..., 0, 0, 0],
...,
[0, 1, 0, ..., 1, 0, 1],
[1, 0, 0, ..., 0, 1, 1],
[0, 0, 0, ..., 0, 0, 0]]]]]], dtype=uint8)
Coordinates:
* plantbarcode (plantbarcode) object 'A2'
* tind_s (tind_s) int64 60
* induction frame (induction frame) object 'Fp' 'Fmp'
* jobdate (jobdate) datetime64[ns] 2020-06-03
Dimensions without coordinates: y, x
和print(ds)
print(ds)
<xarray.DataArray (jobdate: 18, plantbarcode: 2, tind_s: 3, induction frame: 2, y: 640, x: 480)>
array([[[[[[ 0., 0., 0., ..., 0., 0., 1.],
[ 0., 0., 1., ..., 2., 0., 0.],
[ 0., 0., 0., ..., 0., 0., 0.],
...,
[ 1., 0., 0., ..., 7., 0., 0.],
[ 0., 2., 4., ..., 0., 0., 4.],
[ 0., 1., 0., ..., 1., 0., 0.]],
[[ 0., 1., 0., ..., 0., 1., 0.],
[ 0., 0., 1., ..., 1., 2., 1.],
[ 0., 1., 1., ..., 1., 0., 0.],
...,
[ 1., 2., 2., ..., 0., 1., 1.],
[ 1., 1., 1., ..., 0., 1., 0.],
[ 0., 0., 2., ..., 0., 0., 1.]]],
[[[nan, nan, nan, ..., nan, nan, nan],
[nan, nan, nan, ..., nan, nan, nan],
[nan, nan, nan, ..., nan, nan, nan],
...
[nan, nan, nan, ..., nan, nan, nan],
[nan, nan, nan, ..., nan, nan, nan],
[nan, nan, nan, ..., nan, nan, nan]]],
[[[ 0., 0., 0., ..., 0., 0., 0.],
[ 1., 1., 0., ..., 0., 0., 0.],
[ 0., 0., 2., ..., 0., 0., 0.],
...,
[ 1., 0., 0., ..., 0., 1., 0.],
[ 1., 0., 0., ..., 0., 0., 1.],
[ 1., 0., 0., ..., 1., 1., 0.]],
[[ 0., 0., 0., ..., 0., 1., 1.],
[ 2., 2., 0., ..., 0., 0., 1.],
[ 2., 1., 1., ..., 0., 0., 0.],
...,
[ 0., 1., 0., ..., 1., 0., 1.],
[ 1., 0., 0., ..., 0., 1., 1.],
[ 0., 0., 0., ..., 0., 0., 0.]]]]]])
Coordinates:
* plantbarcode (plantbarcode) object 'A1' 'A2'
* tind_s (tind_s) int64 0 40 60
* induction frame (induction frame) object 'Fp' 'Fmp'
* jobdate (jobdate) datetime64[ns] 2020-06-01 ... 2020-06-03
Dimensions without coordinates: y, x
我不明白nan数组是从哪里来的。对我来说,无论在 concat 中使用什么 dim,这对每个条目(在本例中为 18 个文件)都有一个坐标值,即使它们不是唯一的,但其他 dims 仅显示为唯一值,这对我来说也很奇怪。
如果有人愿意下载一个小数据集,这里是一个 link(很抱歉反对 link 中的建议,我会尝试提出一个可以生成的合成数据集即时)
我在 xarray 邮件列表上看到了你的问题。很难调试这个问题,因为它很复杂并且取决于您的数据。如果您可以稍微简化它并使用合成数据而不是您的数据文件,那就太好了——请参阅 https://matthewrocklin.com/blog/work/2018/02/28/minimal-bug-reports 以获取有关这方面的建议。
如果您分享 print(arr)
的输出,这也会很有帮助,这样我们就可以了解您的 DataArrays 的内容和结构。
您的原始代码在 arr.expand_dims(dims={'tind_s': tind})
中包含一个微妙的错误(拼写错误):我猜您想要 dim
而不是 dims
,后者被 xarray 解释为新的维度标签(参见 doc)。此外,tind
在这里用作沿新维度创建的元素数,这可能也不是您想要的。
您的其他尝试(即在创建 DataArray
之前扩展数据维度)是 IMO 更好的方法,但它可以进一步改进。鉴于您在同一串联维度上有多个标签,我建议您创建一个多索引并将其分配给串联维度,即
import numpy as np
import pandas as pd
import xarray as xr
da_list = []
props = []
prop_names = ['experiment', 'plantbarcode', 'tind']
for i in range(10):
tind = i
indf = ['Fp', 'Fmp']
data = np.ones((2, 640, 480)) * i
da = xr.DataArray(
data=data[None, ...],
dims=('props', 'frame', 'y', 'x'),
coords={'frame': indf}
)
props.append((f'experiment{i}', i*2, i))
da_list.append(da)
prop_idx = pd.MultiIndex.from_tuples(props, names=prop_names)
da_concat = xr.concat(da_list, 'props')
da_concat.coords['props'] = prop_idx
给出:
<xarray.DataArray (props: 10, frame: 2, y: 640, x: 480)>
array([[[[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
...,
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.]],
[[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
...,
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.]]],
[[[1., 1., 1., ..., 1., 1., 1.],
[1., 1., 1., ..., 1., 1., 1.],
[1., 1., 1., ..., 1., 1., 1.],
...
[8., 8., 8., ..., 8., 8., 8.],
[8., 8., 8., ..., 8., 8., 8.],
[8., 8., 8., ..., 8., 8., 8.]]],
[[[9., 9., 9., ..., 9., 9., 9.],
[9., 9., 9., ..., 9., 9., 9.],
[9., 9., 9., ..., 9., 9., 9.],
...,
[9., 9., 9., ..., 9., 9., 9.],
[9., 9., 9., ..., 9., 9., 9.],
[9., 9., 9., ..., 9., 9., 9.]],
[[9., 9., 9., ..., 9., 9., 9.],
[9., 9., 9., ..., 9., 9., 9.],
[9., 9., 9., ..., 9., 9., 9.],
...,
[9., 9., 9., ..., 9., 9., 9.],
[9., 9., 9., ..., 9., 9., 9.],
[9., 9., 9., ..., 9., 9., 9.]]]])
Coordinates:
* frame (frame) <U3 'Fp' 'Fmp'
* props (props) MultiIndex
- experiment (props) object 'experiment0' 'experiment1' ... 'experiment9'
- plantbarcode (props) int64 0 2 4 6 8 10 12 14 16 18
- tind (props) int64 0 1 2 3 4 5 6 7 8 9
Dimensions without coordinates: y, x