Добавить строки в массив записей NumPy - PullRequest
7 голосов
/ 13 ноября 2009

Есть ли способ добавить строку в rec.array () NumPy? Например,

x1=np.array([1,2,3,4])
x2=np.array(['a','dd','xyz','12'])
x3=np.array([1.1,2,3,4])
r = np.core.records.fromarrays([x1,x2,x3],names='a,b,c')

append(r,(5,'cc',43.0),axis=0)

Самый простой способ - извлечь весь столбец как типы nd.array (), добавить отдельные элементы в каждый столбец, а затем перестроить rec.array (). Этот метод, к сожалению, был бы неэффективным. Есть ли другой способ, не отделяя перестройку rec.array ()?

Приветствия

Eli

Ответы [ 3 ]

6 голосов
/ 13 ноября 2009

Вы можете изменить размер массивов на месте. Это быстрее, чем преобразование в списки, а затем обратно в массивные массивы, и при этом используется меньше памяти.

print (r.shape)
# (4,)
r.resize(5)   
print (r.shape)
# (5,)
r[-1] = (5,'cc',43.0)
print(r)

# [(1, 'a', 1.1000000000000001) 
#  (2, 'dd', 2.0) 
#  (3, 'xyz', 3.0) 
#  (4, '12', 4.0)
#  (5, 'cc', 43.0)]

Если памяти недостаточно для расширения массива на месте, операция изменения размера (или добавления) может заставить NumPy выделить пространство для совершенно нового массива и скопировать старые данные в новое местоположение. Это, естественно, довольно медленно, поэтому вы должны стараться избегать использования resize или append, если это возможно. Вместо этого предварительно выделите массивы достаточного размера с самого начала (даже если они несколько больше, чем в конечном итоге необходимо).

0 голосов
/ 21 октября 2015

Расширение ответа @ unutbu Я публикую более общую функцию, которая добавляет любое количество строк:

def append_rows(arrayIN, NewRows):
    """Append rows to numpy recarray.

    Arguments:
      arrayIN: a numpy recarray that should be expanded
      NewRows: list of tuples with the same shape as `arrayIN`

    Idea: Resize recarray in-place if possible.
    (only for small arrays reasonable)

    >>> arrayIN = np.array([(1, 'a', 1.1), (2, 'dd', 2.0), (3, 'x', 3.0)],
                           dtype=[('a', '<i4'), ('b', '|S3'), ('c', '<f8')])
    >>> NewRows = [(4, '12', 4.0), (5, 'cc', 43.0)]
    >>> append_rows(arrayIN, NewRows)
    >>> print(arrayIN)
    [(1, 'a', 1.1) (2, 'dd', 2.0) (3, 'x', 3.0) (4, '12', 4.0) (5, 'cc', 43.0)]

    Source: http://stackoverflow.com/a/1731228/2062965
    """
    # Calculate the number of old and new rows
    len_arrayIN = arrayIN.shape[0]
    len_NewRows = len(NewRows)
    # Resize the old recarray
    arrayIN.resize(len_arrayIN + len_NewRows, refcheck=False)
    # Write to the end of recarray
    arrayIN[-len_NewRows:] = NewRows

Комментарий

Хочу подчеркнуть, что предварительное выделение массива, по крайней мере достаточно большого, является наиболее разумным решением (если у вас есть представление об окончательном размере массива)! Предварительное распределение также экономит много времени.

0 голосов
/ 13 ноября 2009
np.core.records.fromrecords(r.tolist()+[(5,'cc',43.)])

Тем не менее он разделяется, на этот раз по строкам. Может лучше?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...