如何使用numpy在不知道矩阵大小的情况下将行向量附加到空矩阵



行是一个343x30的实数矩阵。我试图将行向量从行附加到真行和假行,但它只添加第一行,之后什么都不做。我试过vstack,也试过把example作为2d数组([example](,但它破坏了我的pycharm。我能做什么?

true_rows = []
true_labels = []
false_rows = []
false_labels = []
i = 0
for example in rows:
if question.match(example):
true_rows = np.append(true_rows , example , axis=0)
true_labels.append(labels[i])
else:
#false_rows = np.vstack(false_rows, example_t)
false_rows = np.append(false_rows, example, axis=0)
false_labels.append(labels[i])
i += 1

您只能使用一个简单的列表来附加行,然后将该列表转换为numpy数组,例如:

exemple1 = np.array([1,2,3,4,5])
exemple2 = np.array([6,7,8,9,10])
exemple3 = np.array([11,12,13,14,15])  
true_rows = []
true_rows.append(exemple1)
true_rows.append(exemple2)
true_rows.append(exemple3)
true_rows = np.array(true_rows)

你会得到这样的结果:

true_rows = array([[ 1,  2,  3,  4,  5],
[ 6,  7,  8,  9, 10],
[11, 12, 13, 14, 15]])

如果你想得到这样的一维数组,你也可以使用np.concatenate

true_rows = np.concatenate(true_rows , axis =0)

你会得到这样的结果:

true_rows = array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15])

您对[]np.append的使用表明您正在尝试用数组模拟常见的列表附加模型。您至少阅读了足够多的np.append文档,知道您需要使用axis,并且它返回了一个新数组(文档非常清楚,这是一个副本(。

但是,您是否用一个小例子测试了这个想法,并实际查看结果(一步一步(?

In [326]: rows = []
In [327]: rows = np.append(rows, np.arange(3), axis=0)
In [328]: rows
Out[328]: array([0., 1., 2.])    
In [329]: rows.shape
Out[329]: (3,)

第一个追加没有任何作用——结果与arange(3)相同。

In [330]: rows = np.append(rows, np.arange(3), axis=0)
In [331]: rows
Out[331]: array([0., 1., 2., 0., 1., 2.])
In [332]: rows.shape
Out[332]: (6,)

你明白为什么吗?我们将轴0上的2个1d数组连接起来,形成一个1d。

使用[]作为起始点与使用此阵列相同:

In [333]: np.array([])
Out[333]: array([], dtype=float64)
In [334]: np.array([]).shape
Out[334]: (0,)

对于axisnp.append只是对concatenate:的调用

In [335]: np.concatenate(( [], np.arange(3)), axis=0)
Out[335]: array([0., 1., 2.])

np.append排序看起来像列表追加,但它不是克隆。这实际上只是一种命名不好的使用concatenate的方法。如果不真正了解尺寸,就无法正确使用它。np.append有一个例子,其中有一个与concatenate非常相似的错误。

在循环中重复使用这些阵列concatenates不是一个好主意。正如你所发现的,很难把尺寸弄对。即使它有效,它也很慢,因为每一步都会产生一个副本(随着迭代而增长(。

这就是为什么另一个答案坚持列表附加。

vstack类似于轴为0的concatenate,但它确保所有参数都是2d。但如果数字列不同,就会引发一个错误:

In [336]: np.vstack(( [],np.arange(3)))
Traceback (most recent call last):
File "<ipython-input-336-22038d6ef0f7>", line 1, in <module>
np.vstack(( [],np.arange(3)))
File "<__array_function__ internals>", line 180, in vstack
File "/usr/local/lib/python3.8/dist-packages/numpy/core/shape_base.py", line 282, in vstack
return _nx.concatenate(arrs, 0)
File "<__array_function__ internals>", line 180, in concatenate
ValueError: all the input array dimensions for the concatenation axis must match exactly, but along dimension 1, the array at index 0 has size 0 and the array at index 1 has size 3
In [337]: np.vstack(( [0,0,0],np.arange(3)))
Out[337]: 
array([[0, 0, 0],
[0, 1, 2]])

如果所有要连接的都是(n,30(数组的行,那么您确实知道结果的列大小。

In [338]: res = np.zeros((0,3))
In [339]: np.vstack(( res, np.arange(3)))
Out[339]: array([[0., 1., 2.]])

如果你注意形状的细节,就可以迭代地创建一个数组。


但是与其逐个收集行,为什么不创建一个mask并进行一次收集呢。

大致做

mask = np.array([question.match(example) for example in rows])
true_rows = rows[mask]
false_rows = rows[~mask]

这仍然需要迭代,但总体上应该更快。

相关内容

最新更新