不使用循环将2D的numpy数组转换为3D数组

3
我有一个形状为(t*40,6)的二维数组,我想将其转换为形状为(t,40,5)的三维数组,用于LSTM的输入数据层。如下图所示,描述了所需的转换方式。这里,F1..5是5个输入特征,T1...40是LSTM的时间步长,C1...t是各种训练示例。基本上,对于每个唯一的“Ct”,我都希望有一个“T X F”的二维数组,并沿第3个维度进行连接。只要每个Ct在不同的维度中即可,我不介意失去“Ct”的值。

enter image description here

我有以下代码,通过循环遍历每个唯一的Ct,并在第三维度中添加“T X F” 2D数组。
# load 2d data
data = pd.read_csv('LSTMTrainingData.csv')

trainX = []

# loop over each unique ct and append the 2D subset in the 3rd dimension
for index, ct in enumerate(data.ct.unique()):
    trainX.append(data[data['ct'] == ct].iloc[:, 1:])

然而,有超过180万个这样的Ct,因此循环遍历每个唯一的Ct会相当缓慢。寻求如何更快地执行此操作的建议。
编辑:
data_3d = array.reshape(t,40,6)
trainX = data_3d[:,:,1:]

这是原始问题的解决方案。
更新问题并增加一个问题:T1...40个时间步骤可以有最高40步,但也可能少于40步。其余的值可以在可用的40个插槽中为'np.nan'。

等CT值是否总是连续的? - user2357112
5
这段代码意思是将一个array数组重新排列为t行,每行包含40个元素,每个元素又包含6个数据。 - Vaishali
是的,我正在从 SQL 获取数据,并按 Ct 排序,这样它们就在一起了。 - Chintan Trivedi
1个回答

1

由于所有的Ct长度不同,您别无选择,只能重新构建一个新的块。

但是使用data[data['ct'] == ct]可能是O(n²),所以这是一种糟糕的方法。

这里提供了一种使用Panel的解决方案。cumcount重新编号每个Ct行:

t=5
CFt=randint(0,t,(40*t,6)).astype(float) # 2D data
df= pd.DataFrame(CFt)
df2=df.set_index([df[0],df.groupby(0).cumcount()]).sort_index()
df3=df2.to_panel()

这将自动使用Nan填充缺失的数据。但是它会发出警告:

DeprecationWarning: Panel已被弃用,并将在未来版本中删除。 推荐使用DataFrame上的MultiIndex,通过Panel.to_frame()方法表示这些类型的三维数据。

因此,也许使用df2来管理您的数据是推荐的方式。

循环遍历Cts的索引子集确实可以显著提高速度。我最终采用了多重索引,并在小批次中预先分配trainX,因此我会在循环期间每隔一段时间将trainX数组的小批量存储到磁盘上。总体而言,现在我可以在大约13分钟内完成所有操作,而根据先前的方法估计需要25天! - Chintan Trivedi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接