我目前正在修补Scikit-Learn函数,其中一行需要一个具有2维的NumPy数组。但是,我正在使用的数据是一个包含3个维度的NumPy数组,这会引发错误“解压缩的值太多。”
我正在调用K-Means函数fit
来聚类数据。我的问题归结为以下一行代码,假设X
是我传入的ndarray
:
n_samples, n_features = X.shape
X
是一个包含3个维度的数组,如下所示:
X = np.array([[[1, 2, 3],
[4, 5, 6]],
[[7, 8, 9],
[10, 11, 12]],
[[13, 14, 15],
[16, 17, 18]]])
数据表示一组具有6个维度的数据点的时间序列。例如,第一个元素[[1, 2, 3], [4, 5, 6]]
表示一个时间序列,其中包含2个时间段的样本,每个样本都有3个维度。
我已对k_means_
代码进行了修补,以允许我在ndarray
ndarray
上执行群集。我的目标是在2D阵列上执行k-means。
是否可以将3D ndarray的形状设置为2个元素?例如,我尝试将3D数组转换为2D对象数组,但最终会转换回3D数组。
np.array([[x.astype(object) for x in c] for c in combined])
同样,以下代码也会转换回3D数组。
np.array([[np.array(x) for x in c] for c in combined])
列表推导[[x.astype(object) for x in c] for c in combined]
看起来像是创建了正确的数组,但由于它是类型列表,它不再适用于该函数。
我正在寻找将3D NumPy数组“转换”为2维的方法。任何帮助将不胜感激!
注意:我不是在寻找一种重塑数组的方法。我需要保留所有尺寸,但更改形状以忽略其中一个尺寸。
答案 0 :(得分:1)
要制作一个数组数组,我们必须发挥一些技巧,因为np.array
试图尽可能地创建一个高维数组。如果子阵列的大小不一样,但如果它们完全相同,我们就必须对抗它。
这是一种方式:
从3d数组开始:
In [812]: arr = np.arange(24).reshape(2,3,4)
和一个正确大小的空对象数组(但是展平)
In [813]: A = np.empty((6,),object)
复制值(再次使用展平),并重塑为目标形状
In [814]: A[:]=list(arr.reshape(-1,4))
In [815]: A=A.reshape(2,3)
In [816]: A
Out[816]:
array([[array([0, 1, 2, 3]), array([4, 5, 6, 7]), array([ 8, 9, 10, 11])],
[array([12, 13, 14, 15]), array([16, 17, 18, 19]),
array([20, 21, 22, 23])]], dtype=object)
所以现在我们有一个(2,3)数组,其形状可以解压缩。
我尝试从np.empty((2,3),object)
开始,但无法让A[:,:]=...
作业完成。为了重塑这个对象,我们必须将arr
拆分成一个数组列表。对象数组就像列表一样,是一个指针数组。
但是scikit
函数会接受这样的数组吗? (通过形状障碍后)。我怀疑物体重塑是一个短视的解决方案。
In [824]: [[x.astype(object) for x in c] for c in arr]
Out[824]:
[[array([0, 1, 2, 3], dtype=object),
array([4, 5, 6, 7], dtype=object),
array([8, 9, 10, 11], dtype=object)],
[array([12, 13, 14, 15], dtype=object),
array([16, 17, 18, 19], dtype=object),
array([20, 21, 22, 23], dtype=object)]]
In [825]: _[0][0].shape
Out[825]: (4,)
这将创建一个嵌套的列表列表,内部元素为(4,)对象数组。将其包裹在np.array
中,并使用dtype对象重新创建一个3d数组。
重塑,由于某种未知原因,您不想保留数字dtype
In [828]: arr.reshape(2,-1)
Out[828]:
array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]])
In [829]: arr.reshape(-1,4)
Out[829]:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]])