我有一个包含光谱随时间演变的数据文件。我可以用np.loadtxt
加载数据,但这会返回一个包含3列的2D数组--这是文件的准确表示,但不是每个时间间隔循环的最佳结构。我想重塑数据到一个立方体,其中每个切片包含频谱在一个单一的时间步骤。
输入文件如下所示:
Time Wavelength Flux
1.0 100 30
1.0 101 29
1.0 102 31
...
1.0 200 43
2.0 100 30
2.0 101 29.5
...
2.0 200 42
3.0 100 31
3.0 101 32
...
100 200 37
np.loadtxt
返回一个nx3数组,其中n是文件中的行数。我希望我的代码使用时间列增量为断点的行将数据格式化为多维数据集。换句话说,我想要一个光谱列表,每个光谱比前一个光谱晚一步。这是我的意思的视觉曲目。
我可以想出许多方法来手动循环数据,并强制将其转换成可用的格式,但这似乎既非unpythonic的,也是计算效率低下的。我将在许多不同的文件上大量使用这段代码,所以我不能在单个片中的行数中硬编码。我看了一下np.shape
,但是它似乎没有一个明显的更快的方法来完成这个任务。
是否有更快、更多的琵琶方法来完成这一任务?还是每次手动确定断点时循环文件的唯一可行方法?
发布于 2021-07-09 17:26:43
嗯,我认为你的问题可以有一些额外的信息,因为,在这些数据中,具有不同时间步骤的行数总是相同的?在其他文件中,它们也会是一样的?
不管怎么说,当然您知道您有多少,您可以在数组中使用numpy.split
,在同一时间块中分隔数组。
如果时间相同的行数量不同,则可以使用for
循环和numpy.append
来同时创建子数组。
编辑
从您给出的内容来看,您基本上需要知道每个文件的时间步骤中有多少行。
由于我没有您的数据,所以我构建了一个artificial_data来举例说明
import numpy as np
length=np.random.randint(6,9)
artificial_data = np.transpose((np.concatenate((np.ones(length),2*np.ones(length),3*np.ones(length),4*np.ones(length))),
np.concatenate((np.random.rand(length),np.random.rand(length),np.random.rand(length),np.random.rand(length))),
np.concatenate((np.random.rand(length),np.random.rand(length),np.random.rand(length),np.random.rand(length)))))
artificial_data
这会给出(这些是随机数,所以每次运行时都会改变)。
array([[1. , 0.62337349, 0.84582971],
[1. , 0.38484415, 0.57365805],
[1. , 0.80504472, 0.67706586],
[1. , 0.49799682, 0.69909408],
[1. , 0.06563674, 0.51799158],
[1. , 0.65680522, 0.7616487 ],
[1. , 0.11497811, 0.67833476],
[2. , 0.74605054, 0.40117761],
[2. , 0.47544047, 0.40270957],
[2. , 0.79241801, 0.92569317],
[2. , 0.69839158, 0.21629401],
[2. , 0.7169591 , 0.32631124],
[2. , 0.8832162 , 0.55114389],
[2. , 0.91455405, 0.28574292],
[3. , 0.61089879, 0.77563826],
[3. , 0.15776237, 0.64906268],
[3. , 0.80971068, 0.76695185],
[3. , 0.88994052, 0.07681381],
[3. , 0.71479789, 0.50768739],
[3. , 0.56042634, 0.25032607],
[3. , 0.44866057, 0.54832829],
[4. , 0.2643985 , 0.62251815],
[4. , 0.21353805, 0.91354626],
[4. , 0.75809504, 0.71601593],
[4. , 0.84296248, 0.87818252],
[4. , 0.95029666, 0.10553645],
[4. , 0.42500662, 0.92322183],
[4. , 0.95176257, 0.63409806]])
现在,从第一列中,我们可以确定最大时间步长(我不知道这个量在您的情况下是否有变化)。
对于这个数字,我们基本上知道如何分割数据,所以我们转换数据,删除包含时间步长的第一列,我们把它转换回原来的形式,然后根据次数进行拆分。这看起来就像
num_of_time_steps = int(max(np.transpose(artificial_data)[0]))
separated_data = np.split(np.transpose(np.transpose(artificial_data)[1:]),num_of_time_steps)
separated_data
它提供所需的输出。
[array([[0.62337349, 0.84582971],
[0.38484415, 0.57365805],
[0.80504472, 0.67706586],
[0.49799682, 0.69909408],
[0.06563674, 0.51799158],
[0.65680522, 0.7616487 ],
[0.11497811, 0.67833476]]),
array([[0.74605054, 0.40117761],
[0.47544047, 0.40270957],
[0.79241801, 0.92569317],
[0.69839158, 0.21629401],
[0.7169591 , 0.32631124],
[0.8832162 , 0.55114389],
[0.91455405, 0.28574292]]),
array([[0.61089879, 0.77563826],
[0.15776237, 0.64906268],
[0.80971068, 0.76695185],
[0.88994052, 0.07681381],
[0.71479789, 0.50768739],
[0.56042634, 0.25032607],
[0.44866057, 0.54832829]]),
array([[0.2643985 , 0.62251815],
[0.21353805, 0.91354626],
[0.75809504, 0.71601593],
[0.84296248, 0.87818252],
[0.95029666, 0.10553645],
[0.42500662, 0.92322183],
[0.95176257, 0.63409806]])]
现在,您可以通过分离数据的第一个索引从给定的时间步骤访问每个数据,如
data_with_time_step_i = separated_data[i]
希望这能帮到你,我不能说出比这更简单的东西
https://stackoverflow.com/questions/68320546
复制相似问题