xarray:重塑数据形状,拆分维度

2024-06-16 14:08:46 发布

您现在位置:Python中文网/ 问答频道 /正文

我在xarray中有一个数据集,其维度如下:

Dimensions:      (subject: 30, session: 5, time: 45000)
Coordinates:
  * subject      (subject) object '110' '112' '114' '117' ...
  * session      (session) object 'week1' 'week2' 'week3' ...
  * time         (time) timedelta64[ns] 00:00:00 00:00:00.040000 ...

我想将每个试验(受试者/会话组合)分成更小的时间段,例如分成3个段,每个段有15000个值,结果维可能如下所示:

^{pr2}$

我试过很多东西,但都没有成功,怎么能做到呢?在

我一直在尝试的一件事,似乎很接近,就是创建一个新的多重索引并将其拆散。在

segment_data = np.repeat(range(3),len(ds.time)//3)
segment = xr.Variable(dims='time',data=segment_data)
newtime_data = np.tile(ds.time[:len(ds.time)//3],3)
newtime = xr.Variable(dims='time',data=newtime_data)
dsr = ds.assign_coords(segment=segment,newtime=newtime)
dsr = dsr.set_index(segment='segment',newtime='newtime')
dsr = dsr.stack(fragment=['segment','newtime'])

然而,最后一行占用了大量内存,似乎创建了一个维度fragment: len(ds.time)**2,这似乎不对。我也不知道在这之后我要做什么(unstack('fragment')?)。在

编辑:还有一些尝试把我带到了这里:

x = np.repeat(range(3),15000)
y = np.tile(ds.time[:len(ds.time)//3],3)
dsr = (ds.assign_coords(segment=x,time2=y)
      .set_index(fragment=['segment','time2'])
      .unstack('fragment'))

因此:

(subject: 30, segment: 3, session: 5, time: 45000, time2: 15000)

这似乎很接近,但并不完全存在,因为现在每个time2点都有45000个值,而它应该是一个单一值:

dsr.isel(subject=0,segment=0,session=0,time2=0)
# (time: 45000)

编辑:我终于找到了一个办法,看看我的答案。欢迎进一步建议!在


Tags: datalenobjecttimesessionnpdssegment
1条回答
网友
1楼 · 发布于 2024-06-16 14:08:46

首先确保有两个新尺寸标注的标签。在这种情况下,如下所示:

x = range(3) # 3 segments
y = ds.time[:len(ds.time)//3] # the first 1/3rd of the time labels

然后从这些标签*创建一个pandas多重索引。在

^{pr2}$

最后,用这个新索引替换数据集中的time索引,然后取消其级别以创建两个必需的维度。在

dsr = ds.assign(time=ind).unstack('time')

您可能需要使用rename重命名新维度:

dsr = dsr.rename({'new_time':'time'})

结果尺寸:

(subject: 30, segment: 3, session: 5, time: 15000)

现在唯一关闭的是维度的顺序(理想情况下segment和{}应该交换)。我以为transpose会有帮助,但是"although the order of dimensions on each array will change, the dataset dimensions themselves will remain in fixed (sorted) order."**所以我可能会这样接受它。在

*请注意,您将无法使用要拆分的维度的名称,因此这里有'new_time'。一个不必要的限制assign

**另一个我无法解释的限制。

相关问题 更多 >