Numpy - 向数组添加行

244
如何向numpy数组添加行?
我有一个名为A的数组:
A = array([[0, 1, 2], [0, 2, 0]])

如果X中每一行的第一个元素满足特定条件,我希望将这些行从另一个数组X添加到此数组中。

Numpy数组似乎没有像列表那样的“append”方法。

如果A和X是列表,我只需执行以下操作:

for i in X:
    if i[0] < 3:
        A.append(i)

有没有一种numpythonic的方法来做同样的事情?

谢谢, S ;-)


参见https://dev59.com/92oy5IYBdhLWcg3wiegp - Thomas Ahle
10个回答

253

你可以这样做:

newrow = [1, 2, 3]
A = numpy.vstack([A, newrow])

4
为什么它被废弃了?我在文档中没有看到任何说明。 - Georgy
1
@Georgy 老实说,我也不知道。我和你一样在这里寻找答案 :-)。我现在记不起来为什么写了上面的评论。可能是因为我在文档中看到它已经过时了。但是现在看文档...它并没有这么说。他们是否将其弃用,然后又改变主意,决定放弃并删除它会让太多人感到烦恼,这是可能的吗? - Kris

153

"X"是什么?如果它是一个二维数组,你如何将其行与数字进行比较:i < 3

根据提问者的评论进行编辑:

A = array([[0, 1, 2], [0, 2, 0]])
X = array([[0, 1, 2], [1, 2, 0], [2, 1, 2], [3, 2, 0]])

A中第一个元素小于3的所有行添加到X中:

import numpy as np
A = np.vstack((A, X[X[:,0] < 3]))

# returns: 
array([[0, 1, 2],
       [0, 2, 0],
       [0, 1, 2],
       [1, 2, 0],
       [2, 1, 2]])

1
抱歉,你说得对!假设一个2D数组,每行的第一个元素必须满足某个条件。我会进行编辑的。谢谢,S;-) - Darren J. Fitzpatrick
2
请注意,通过进行这种类型的操作,您会破坏Numpy为现有数组A预分配内存所做的良好工作。 显然,对于像本答案中的小问题,这不是问题,但对于大数据来说可能更麻烦。 - dtlussier

57

由于这个问题是7年前的,我正在使用的最新版本是numpy 1.13和Python3。我正在做相同的事情,添加一个矩阵行,请记得将第二个参数用双括号括起来,否则会引发维度错误。

在这里,我正在添加矩阵A。

1 2 3
4 5 6

一排

7 8 9

np.r_ 中的用法相同。

A = [[1, 2, 3], [4, 5, 6]]
np.append(A, [[7, 8, 9]], axis=0)

    >> array([[1, 2, 3],
              [4, 5, 6],
              [7, 8, 9]])
#or 
np.r_[A,[[7,8,9]]]

对于对此感兴趣的人,如果您想要添加一列,

array = np.c_[A,np.zeros(#A的行数大小)]

按照我们之前在矩阵A上所做的操作,向其添加一列。

np.c_[A, [2,8]]

>> array([[1, 2, 3, 2],
          [4, 5, 6, 8]])

如果您想要在前面添加,只需翻转参数的顺序,即:

np.r_([[7, 8, 9]], A)

    >> array([[7, 8, 9],
             [1, 2, 3],
             [4, 5, 6]])

21

如果每一行后都不需要进行计算,那么使用Python添加行要比使用numpy快得多。以下是在Python 3.6和numpy 1.14下添加100行的时间测试:

import numpy as np 
from time import perf_counter, sleep

def time_it():
    # Compare performance of two methods for adding rows to numpy array
    py_array = [[0, 1, 2], [0, 2, 0]]
    py_row = [4, 5, 6]
    numpy_array = np.array(py_array)
    numpy_row = np.array([4,5,6])
    n_loops = 100

    start_clock = perf_counter()
    for count in range(0, n_loops):
       numpy_array = np.vstack([numpy_array, numpy_row]) # 5.8 micros
    duration = perf_counter() - start_clock
    print('numpy 1.14 takes {:.3f} micros per row'.format(duration * 1e6 / n_loops))

    start_clock = perf_counter()
    for count in range(0, n_loops):
        py_array.append(py_row) # .15 micros
    numpy_array = np.array(py_array) # 43.9 micros       
    duration = perf_counter() - start_clock
    print('python 3.6 takes {:.3f} micros per row'.format(duration * 1e6 / n_loops))
    sleep(15)

#time_it() prints:

numpy 1.14 takes 5.971 micros per row
python 3.6 takes 0.694 micros per row
因此,解决最初问题的简单方法是使用vstack()将行转换为numpy数组后添加新行。但更现实的解决方案应考虑到在这些情况下vstack的性能较差。如果您不需要在每次添加后对数组运行数据分析,则最好将新行缓冲到Python行列表中(实际上是一个列表的列表),然后在进行任何数据分析之前将它们作为一组添加到numpy数组中使用vstack()。

11

你也可以这样做:

newrow = [1,2,3]
A = numpy.concatenate((A,newrow))

2
嗯,当我尝试这个时,它只是添加到了A的末尾,而不是像OP请求的那样添加一个新行。 - Todd Curry
14
可能是 np.concatenate((A, newrow), axis=0)。该函数将数组 A 和 newrow 沿着 0 轴连接起来。 - Konstantinos Roditakis
3
截至numpy版本“1.12.1”(以及Python 3),似乎尝试将向量连接到矩阵会引发“ValueError:所有输入数组必须具有相同的维数”。看起来它希望在把向量连接之前将其显式地重塑为列向量或行向量。 - MRule
3
您可以按照@Flora PJ Li的答案(https://dev59.com/N2865IYBdhLWcg3wTczg#47845065)使用双方括号来解决该问题。 newrow = [[1,2,3]] - Tom Saleeba

8
import numpy as np
array_ = np.array([[1,2,3]])
add_row = np.array([[4,5,6]])

array_ = np.concatenate((array_, add_row), axis=0)

4
我使用'np.vstack',它更快,例如:
import numpy as np

input_array=np.array([1,2,3])
new_row= np.array([4,5,6])

new_array=np.vstack([input_array, new_row])

4

我使用numpy.insert(arr, i, the_object_to_be_added, axis)函数,以便在第i行(axis=0)或者第i列(axis=1)插入object_to_be_added对象。

import numpy as np

a = np.array([[1, 2, 3], [5, 4, 6]])
# array([[1, 2, 3],
#        [5, 4, 6]])

np.insert(a, 1, [55, 66], axis=1)
# array([[ 1, 55,  2,  3],
#        [ 5, 66,  4,  6]])

np.insert(a, 2, [50, 60, 70], axis=0)
# array([[ 1,  2,  3],
#        [ 5,  4,  6],
#        [50, 60, 70]])

虽然这个讨论已经很久远了,但我希望它能对某些人有所帮助。


3
如果你可以一次性完成构建,那么像使用fancy-indexing的vstack方法就是一个不错的选择。但如果你的条件更加复杂或者行数据是动态获取的,那么你可能需要动态增长数组。实际上,像这样动态增长数组的numpythonic方式是动态增长列表:
A = np.array([[1,2,3],[4,5,6]])
Alist = [r for r in A]
for i in range(100):
    newrow = np.arange(3)+i
    if i%5:
        Alist.append(newrow)
A = np.array(Alist)
del Alist
    列表非常适合这种访问模式;在列表形式下,您没有方便的numpy多维索引,但只要您在添加行数组,很难找到比行数组列表更好的选择。

2
你可以使用numpy.append()将行附加到numpy数组中并稍后调整形状以形成矩阵。
import numpy as np
a = np.array([1,2])
a = np.append(a, [3,4])
print a
# [1,2,3,4]
# in your example
A = [1,2]
for row in X:
    A = np.append(A, row)

由于在添加过程中数组形状会发生改变,因此添加行并不是一个真正的解决方案。 - mins

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