Ответ 1
У NumPy действительно есть функция append, которая, кажется, может делать то, что вы хотите, например,
import numpy as NP
my_data = NP.random.random_integers(0, 9, 9).reshape(3, 3)
new_col = NP.array((5, 5, 5)).reshape(3, 1)
res = NP.append(my_data, new_col, axis=1)
ваш второй фрагмент (hstack) будет работать, если вы добавите еще одну строку, например,
my_data = NP.random.random_integers(0, 9, 16).reshape(4, 4)
# the line to add--does not depend on array dimensions
new_col = NP.zeros_like(my_data[:,-1]).reshape(-1, 1)
res = NP.hstack((my_data, new_col))
hstack
дает тот же результат, что и concatenate((my_data, new_col), axis=1)
, я не уверен, как они сравнивают производительность.
В то время как самый прямой ответ на ваш вопрос, я должен упомянуть, что цикл через источник данных, чтобы заполнить цель через append, а просто отлично в python, не является идиоматическим NumPy. Вот почему:
инициализация массива NumPy относительно дорога, и с помощью этого обычного шаблона python вы берете на себя такую же стоимость на каждой итерации цикла (т.е. каждый добавляемый к массиву NumPy примерно похож на инициализацию нового массива с другим размер).
По этой причине общий шаблон в NumPy для итеративного добавления столбцов в 2D-массив состоит в том, чтобы инициализировать пустой целевой массив один раз (или предварительно выделить один массив 2D NumPy, имеющий все пустые столбцы), последовательно заполнять те пустые столбцы, установив желаемое смещение по столбцам (индекс) - гораздо проще показать, чем объяснить:
>>> # initialize your skeleton array using 'empty' for lowest-memory footprint
>>> M = NP.empty(shape=(10, 5), dtype=float)
>>> # create a small function to mimic step-wise populating this empty 2D array:
>>> fnx = lambda v : NP.random.randint(0, 10, v)
заполняет массив NumPy как в OP, за исключением того, что каждая итерация только повторно устанавливает значения M при последовательных смещениях столбцов
>>> for index, itm in enumerate(range(5)):
M[:,index] = fnx(10)
>>> M
array([[ 1., 7., 0., 8., 7.],
[ 9., 0., 6., 9., 4.],
[ 2., 3., 6., 3., 4.],
[ 3., 4., 1., 0., 5.],
[ 2., 3., 5., 3., 0.],
[ 4., 6., 5., 6., 2.],
[ 0., 6., 1., 6., 8.],
[ 3., 8., 0., 8., 0.],
[ 5., 2., 5., 0., 1.],
[ 0., 6., 5., 9., 1.]])
конечно, если вы заранее не знаете, какой размер должен быть ваш массив просто создайте один намного больше, чем вам нужно, и обрезайте "неиспользуемые" части когда вы закончите заполнять его
>>> M[:3,:3]
array([[ 9., 3., 1.],
[ 9., 6., 8.],
[ 9., 7., 5.]])