【问题标题】:how to append row vectors to an empty matrix without knowing the size of the matrix using numpy?如何使用 numpy 在不知道矩阵大小的情况下将行向量附加到空矩阵?
【发布时间】:2022-01-20 10:42:06
【问题描述】:

rows 是一个 343x30 的实数矩阵。我试图将行向量从行追加到真行和假行,但它只添加第一行,之后不做任何事情。我尝试过 vstack 并尝试将示例作为 2d 数组([示例]),但它使我的 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

【问题讨论】:

  • 一个输入/输出的小例子会很有帮助
  • 你试过 np.concatenate 吗?
  • @yann ziselman 是的,我尝试连接它,它适用于第一次迭代,我得到一个 2by30 矩阵,但第二次我将它与另一个向量连接它说存在尺寸不匹配,这个就是它所说的:ValueError:所有输入数组必须具有相同的维数,但索引 0 处的数组有 3 个维度,索引 1 处的数组有 2 个维度

标签: python arrays numpy


【解决方案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])

【讨论】:

  • 到底是numpy数组还是列表?
  • 最后会是一个numpy数组
【解决方案2】:

您对[]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 有一个错误示例,与您使用连接时遇到的错误非常相似。

在循环中重复使用这些数组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]

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

【讨论】:

    猜你喜欢
    • 2022-11-01
    • 1970-01-01
    • 2018-06-13
    • 1970-01-01
    • 2010-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-25
    相关资源
    最近更新 更多