NumPy 배열에 추가 열을 추가하는 방법


292

NumPy 배열이 있다고 가정 해 보겠습니다 a.

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

그리고 배열을 얻기 위해 0의 열을 추가하고 싶습니다 b.

b = np.array([
    [1, 2, 3, 0],
    [2, 3, 4, 0]
    ])

NumPy에서 어떻게 쉽게 할 수 있습니까?

답변:


181

보다 간단한 해결책과 부팅 속도가 더 빠르다고 생각합니다.

import numpy as np
N = 10
a = np.random.rand(N,N)
b = np.zeros((N,N+1))
b[:,:-1] = a

그리고 타이밍 :

In [23]: N = 10

In [24]: a = np.random.rand(N,N)

In [25]: %timeit b = np.hstack((a,np.zeros((a.shape[0],1))))
10000 loops, best of 3: 19.6 us per loop

In [27]: %timeit b = np.zeros((a.shape[0],a.shape[1]+1)); b[:,:-1] = a
100000 loops, best of 3: 5.62 us per loop

16
(985,1) 모양 np araay를 (985,2) np 배열에 추가하여 (985,3) np 배열로 만들려고하지만 작동하지 않습니다. "입력 배열을 모양 (985)에서 모양 (985,1)으로 브로드 캐스트 할 수 없습니다"오류가 발생합니다. 내 코드에 어떤 문제가 있습니까? 코드 : np.hstack (data, data1)
Outlier

5
@Outlier에서는이 질문에 대한 의견을 묻는 대신 새로운 질문을 게시해야합니다.
JoshAdel

4
@ JoshAdel : ipython에서 코드를 시도했는데 구문 오류가 있다고 생각합니다. 당신은 변화 시도 할 수도 있습니다 a = np.random.rand((N,N))a = np.random.rand(N,N)
hlin117

나는 이것이 OP가 요구 한 것에 대한 과도한 것이라고 생각합니다. Op의 답변은 적절합니다!
lft93ryt

이것은 추가, 삽입 또는 스택을 수행하는 트릭입니다. 답변으로 받아 들여서는 안됩니다. 엔지니어는 아래 답변을 고려해야합니다.
cinqS

325

np.r_[ ... ]np.c_[ ... ] 유용한 대안이다 vstackhstack대괄호 [] 대신에 라운드 ()와 함께,.
몇 가지 예 :

: import numpy as np
: N = 3
: A = np.eye(N)

: np.c_[ A, np.ones(N) ]              # add a column
array([[ 1.,  0.,  0.,  1.],
       [ 0.,  1.,  0.,  1.],
       [ 0.,  0.,  1.,  1.]])

: np.c_[ np.ones(N), A, np.ones(N) ]  # or two
array([[ 1.,  1.,  0.,  0.,  1.],
       [ 1.,  0.,  1.,  0.,  1.],
       [ 1.,  0.,  0.,  1.,  1.]])

: np.r_[ A, [A[1]] ]              # add a row
array([[ 1.,  0.,  0.],
       [ 0.,  1.,  0.],
       [ 0.,  0.,  1.],
       [ 0.,  1.,  0.]])
: # not np.r_[ A, A[1] ]

: np.r_[ A[0], 1, 2, 3, A[1] ]    # mix vecs and scalars
  array([ 1.,  0.,  0.,  1.,  2.,  3.,  0.,  1.,  0.])

: np.r_[ A[0], [1, 2, 3], A[1] ]  # lists
  array([ 1.,  0.,  0.,  1.,  2.,  3.,  0.,  1.,  0.])

: np.r_[ A[0], (1, 2, 3), A[1] ]  # tuples
  array([ 1.,  0.,  0.,  1.,  2.,  3.,  0.,  1.,  0.])

: np.r_[ A[0], 1:4, A[1] ]        # same, 1:4 == arange(1,4) == 1,2,3
  array([ 1.,  0.,  0.,  1.,  2.,  3.,  0.,  1.,  0.])

(둥근 () 대신 대괄호 []의 이유는 파이썬이 예를 들어 사각형에서 1 : 4로 확장되기 때문입니다. 오버로드의 경이로움)


7
방금 이것에 대한 정보를 찾고 있었으며, 이것은 확실히 다른 것보다 처음과 끝에 추가 열을 추가하는 것을 포함하기 때문에 허용 된 것보다 더 나은 대답입니다.
Ay0

2
@ Ay0 정확히, 나는 한 번에 모든 레이어에서 배치로 인공 뉴런 네트워크에 바이어스 유닛을 추가하는 방법을 찾고 있었는데 이것이 완벽한 해답입니다.
gaborous

한 번에 n 개의 열 을 추가하려면 어떻게해야 합니까?
라일리

1
@Riley, 예를 들어 주시겠습니까? 파이썬 3은 "iterable unpacking"을 가지고 있습니다 np.c_[ * iterable ]. expression-lists를 참조하십시오 .
데니스

@denis, 바로 내가 찾던 것이 었습니다!
Riley

148

사용 numpy.append:

>>> a = np.array([[1,2,3],[2,3,4]])
>>> a
array([[1, 2, 3],
       [2, 3, 4]])

>>> z = np.zeros((2,1), dtype=int64)
>>> z
array([[0],
       [0]])

>>> np.append(a, z, axis=1)
array([[1, 2, 3, 0],
       [2, 3, 4, 0]])

3
더 복잡한 열을 삽입 할 때 좋습니다.
Thomas Ahle

6
이것은 @JoshAdel의 대답보다 더 간단하지만 큰 데이터 세트를 처리 할 때 속도가 느립니다. 가독성의 중요성에 따라 둘 중 하나를 선택했습니다.
DVJ

3
append실제로 전화concatenate
rll

53

hstack을 사용하는 한 가지 방법 은 다음과 같습니다.

b = np.hstack((a, np.zeros((a.shape[0], 1), dtype=a.dtype)))

2
이것이 가장 우아한 해결책이라고 생각합니다.
silvado

2
+1-이것이 내가하는 방법입니다-답으로 게시하도록 나를 이겼습니다 :).
블레어

3
dtype매개 변수를 제거하면 필요하지 않으며 심지어는 허용되지 않습니다. 솔루션이 충분히 우아하지만 어레이에 자주 "추가"해야하는 경우에는 사용하지 않도록주의하십시오. 전체 배열을 한 번에 생성하고 나중에 채울 수없는 경우 배열 목록과 hstack한 번에 모두 생성하십시오 .
유미로

1
@eumiro 나는 잘못된 위치에서 dtype을 얻는 방법을 잘 모르겠지만 np.zeros는 모든 것이 플로팅되는 것을 피하기 위해 dtype이 필요합니다 (a가 int 인 동안)
Peter Smit

42

나는 다음과 같은 가장 우아한 것을 발견했다.

b = np.insert(a, 3, values=0, axis=1) # Insert values before column 3

장점은 insert배열 내의 다른 위치에 열 (또는 행)을 삽입 할 수 있다는 것입니다. 또한 단일 값을 삽입하는 대신 전체 열을 쉽게 삽입 할 수 있습니다 (예 : 마지막 열 복제).

b = np.insert(a, insert_index, values=a[:,2], axis=1)

어느 것이나

array([[1, 2, 3, 3],
       [2, 3, 4, 4]])

타이밍 insert의 경우 JoshAdel의 솔루션보다 느릴 수 있습니다.

In [1]: N = 10

In [2]: a = np.random.rand(N,N)

In [3]: %timeit b = np.hstack((a, np.zeros((a.shape[0], 1))))
100000 loops, best of 3: 7.5 µs per loop

In [4]: %timeit b = np.zeros((a.shape[0], a.shape[1]+1)); b[:,:-1] = a
100000 loops, best of 3: 2.17 µs per loop

In [5]: %timeit b = np.insert(a, 3, values=0, axis=1)
100000 loops, best of 3: 10.2 µs per loop

1
이것은 매우 깔끔합니다. insert(a, -1, ...)열을 추가 할 수 없습니다 . 내가 대신에 그냥 붙일 것 같아요.
Thomas Ahle

2
@ThomasAhle을 사용하여 해당 축의 크기를 가져 와서 행이나 열을 추가 할 수 있습니다 a.shape[axis]. 나. 행을 추가하고 행을 추가 np.insert(a, a.shape[0], 999, axis=0)하려면을 수행하십시오 np.insert(a, a.shape[1], 999, axis=1).
blubberdiblub

35

나는 또한이 질문에 관심이 있었고 속도를 비교했습니다.

numpy.c_[a, a]
numpy.stack([a, a]).T
numpy.vstack([a, a]).T
numpy.ascontiguousarray(numpy.stack([a, a]).T)               
numpy.ascontiguousarray(numpy.vstack([a, a]).T)
numpy.column_stack([a, a])
numpy.concatenate([a[:,None], a[:,None]], axis=1)
numpy.concatenate([a[None], a[None]], axis=0).T

입력 벡터에 대해 모두 동일한 작업을 수행합니다 a. 성장 타이밍 a:

여기에 이미지 설명을 입력하십시오

모든 비 연속 변형 (특히 stack/ vstack)은 결국 모든 연속 변형보다 빠릅니다. column_stack(명확성과 속도를 위해) 연속성이 필요한 경우 좋은 옵션으로 보입니다.


줄거리를 재현하는 코드 :

import numpy
import perfplot

perfplot.save(
    "out.png",
    setup=lambda n: numpy.random.rand(n),
    kernels=[
        lambda a: numpy.c_[a, a],
        lambda a: numpy.ascontiguousarray(numpy.stack([a, a]).T),
        lambda a: numpy.ascontiguousarray(numpy.vstack([a, a]).T),
        lambda a: numpy.column_stack([a, a]),
        lambda a: numpy.concatenate([a[:, None], a[:, None]], axis=1),
        lambda a: numpy.ascontiguousarray(
            numpy.concatenate([a[None], a[None]], axis=0).T
        ),
        lambda a: numpy.stack([a, a]).T,
        lambda a: numpy.vstack([a, a]).T,
        lambda a: numpy.concatenate([a[None], a[None]], axis=0).T,
    ],
    labels=[
        "c_",
        "ascont(stack)",
        "ascont(vstack)",
        "column_stack",
        "concat",
        "ascont(concat)",
        "stack (non-cont)",
        "vstack (non-cont)",
        "concat (non-cont)",
    ],
    n_range=[2 ** k for k in range(20)],
    xlabel="len(a)",
    logx=True,
    logy=True,
)

1
멋진 그래프! 그냥 당신이 후드 아래에 있음을 알고 싶습니다 생각 stack, hstack, vstack, column_stack, dstack위에 구축 된 모든 도우미 기능이 있습니다 np.concatenate. 스택 정의 를 추적하여 np.stack([a,a])호출 하는 것을 발견했습니다 np.concatenate([a[None], a[None]], axis=0). 적어도 도우미 함수만큼 빠르다 np.concatenate([a[None], a[None]], axis=0).T는 것을 보여주기 위해 perfplot 에 추가 하는 것이 좋습니다 np.concatenate.
unutbu

@unutbu 추가했습니다.
Nico Schlömer

좋은 도서관, 들어 본 적이 없어! 스택과 concat이 장소를 변경했다는 것을 제외하고는 동일한 플롯을 얻었을 정도로 흥미 롭습니다 (ascont 및 non-cont 변형 모두). 또한 concat-column과 column_stack도 교체되었습니다.
Antony Hatchkins

1
와우,이 음모를 사랑하십시오!
jhegedus

b = [b, a]와 같이 배열에 열을 추가하는 재귀 작업의 경우 일부 명령이 작동하지 않습니다 (크기가 같지 않다는 오류가 발생 함). 불평등 한 크기의 배열 제대로 작동 만이 (즉, 하나는 매트릭스이며, 다른 하나는 1 차원 벡터 인 경우)입니다 c_column_stack
망할 것


12

np.concatenate 도 작동합니다

>>> a = np.array([[1,2,3],[2,3,4]])
>>> a
array([[1, 2, 3],
       [2, 3, 4]])
>>> z = np.zeros((2,1))
>>> z
array([[ 0.],
       [ 0.]])
>>> np.concatenate((a, z), axis=1)
array([[ 1.,  2.,  3.,  0.],
       [ 2.,  3.,  4.,  0.]])

np.concatenatenp.hstack2x1, 2x2 및 2x3 매트릭스 보다 3 배 더 빠른 것 같습니다 . np.concatenate또한 실험에서 행렬을 수동으로 빈 행렬로 복사하는 것보다 약간 빠릅니다. 아래의 Nico Schlömer의 답변과 일치합니다.
Lenar Hoyt

11

M(100,3) ndarray이고 y(100,) ndarray 라고 가정하면 append다음과 같이 사용할 수 있습니다.

M=numpy.append(M,y[:,None],1)

트릭은 사용하는 것입니다

y[:, None]

이것은 y(100, 1) 2D 배열 로 변환 됩니다.

M.shape

이제 준다

(100, 4)

당신은 당신이 알고있는 영웅입니까?! 정확히 1 시간 동안 머리카락을 잡아 당기는 것입니다! 타이!
John Doe

8

나는 성능에 중점을 둔 JoshAdel의 답변을 좋아합니다. 약간의 성능 향상은 0으로 초기화하는 오버 헤드를 피하고 덮어 쓰기 만하는 것입니다. 이것은 N이 클 때 측정 가능한 차이가 있으며 0 대신에 비어 있음을 사용하며 0의 열은 별도의 단계로 작성됩니다.

In [1]: import numpy as np

In [2]: N = 10000

In [3]: a = np.ones((N,N))

In [4]: %timeit b = np.zeros((a.shape[0],a.shape[1]+1)); b[:,:-1] = a
1 loops, best of 3: 492 ms per loop

In [5]: %timeit b = np.empty((a.shape[0],a.shape[1]+1)); b[:,:-1] = a; b[:,-1] = np.zeros((a.shape[0],))
1 loops, best of 3: 407 ms per loop

브로드 캐스트를 사용하여 마지막 열을 0 (또는 다른 값)으로 채울 수 있습니다 b[:,-1] = 0. 또한 매우 큰 어레이의 경우 성능 차이 np.insert()가 무시할 만해 져 np.insert()간결함으로 인해 더 바람직 할 수 있습니다 .
blubberdiblub

7

np.insert 또한 목적을 제공합니다.

matA = np.array([[1,2,3], 
                 [2,3,4]])
idx = 3
new_col = np.array([0, 0])
np.insert(matA, idx, new_col, axis=1)

array([[1, 2, 3, 0],
       [2, 3, 4, 0]])

new_col주어진 인덱스 앞에 idx하나의 축을 따라 여기에 값을 삽입합니다 . 다시 말해, 새로 삽입 된 값은 idx열 을 차지하고 원래와 그 idx뒤로 원래 값을 이동 합니다.


1
참고 insert하나가 (이 질문에 링크 된 문서를 참조) 함수의 이름을 부여 맡기 수 있기 때문에 장소에 있지 않습니다.
jneuendorf

5

numpy 배열에 추가 열을 추가하십시오.

Numpy의 np.append방법은 세 개의 매개 변수를 취합니다. 첫 번째 두 개는 2D numpy 배열이고 세 번째는 추가 할 축을 지시하는 축 매개 변수입니다.

import numpy as np  
x = np.array([[1,2,3], [4,5,6]]) 
print("Original x:") 
print(x) 

y = np.array([[1], [1]]) 
print("Original y:") 
print(y) 

print("x appended to y on axis of 1:") 
print(np.append(x, y, axis=1)) 

인쇄물:

Original x:
[[1 2 3]
 [4 5 6]]
Original y:
[[1]
 [1]]
x appended to y on axis of 1:
[[1 2 3 1]
 [4 5 6 1]]

여기서 x를 y에 추가하는 대신 y를 x에 추가한다는 점에 유의하십시오. 따라서 y의 열 벡터는 결과에서 x의 열 오른쪽에 있습니다.
브라이언 포 eck

4

파티에 약간 늦었지만 아무도이 답변을 게시하지 않았으므로 완전성을 기하기 위해 일반 파이썬 배열에서 목록 이해를 사용 하여이 작업을 수행 할 수 있습니다.

source = a.tolist()
result = [row + [0] for row in source]
b = np.array(result)

4

나를 위해 다음 방법은 매우 직관적이고 단순 해 보입니다.

zeros = np.zeros((2,1)) #2 is a number of rows in your array.   
b = np.hstack((a, zeros))

3

필자의 경우 NumPy 배열에 열을 추가해야했습니다.

X = array([ 6.1101, 5.5277, ... ])
X.shape => (97,)
X = np.concatenate((np.ones((m,1), dtype=np.int), X.reshape(m,1)), axis=1)

X.shape 후 => (97, 2)

array([[ 1. , 6.1101],
       [ 1. , 5.5277],
...

1

이를 위해 특별히 기능이 있습니다. numpy.pad라고합니다

a = np.array([[1,2,3], [2,3,4]])
b = np.pad(a, ((0, 0), (0, 1)), mode='constant', constant_values=0)
print b
>>> array([[1, 2, 3, 0],
           [2, 3, 4, 0]])

다음은 docstring에서 말하는 내용입니다.

Pads an array.

Parameters
----------
array : array_like of rank N
    Input array
pad_width : {sequence, array_like, int}
    Number of values padded to the edges of each axis.
    ((before_1, after_1), ... (before_N, after_N)) unique pad widths
    for each axis.
    ((before, after),) yields same before and after pad for each axis.
    (pad,) or int is a shortcut for before = after = pad width for all
    axes.
mode : str or function
    One of the following string values or a user supplied function.

    'constant'
        Pads with a constant value.
    'edge'
        Pads with the edge values of array.
    'linear_ramp'
        Pads with the linear ramp between end_value and the
        array edge value.
    'maximum'
        Pads with the maximum value of all or part of the
        vector along each axis.
    'mean'
        Pads with the mean value of all or part of the
        vector along each axis.
    'median'
        Pads with the median value of all or part of the
        vector along each axis.
    'minimum'
        Pads with the minimum value of all or part of the
        vector along each axis.
    'reflect'
        Pads with the reflection of the vector mirrored on
        the first and last values of the vector along each
        axis.
    'symmetric'
        Pads with the reflection of the vector mirrored
        along the edge of the array.
    'wrap'
        Pads with the wrap of the vector along the axis.
        The first values are used to pad the end and the
        end values are used to pad the beginning.
    <function>
        Padding function, see Notes.
stat_length : sequence or int, optional
    Used in 'maximum', 'mean', 'median', and 'minimum'.  Number of
    values at edge of each axis used to calculate the statistic value.

    ((before_1, after_1), ... (before_N, after_N)) unique statistic
    lengths for each axis.

    ((before, after),) yields same before and after statistic lengths
    for each axis.

    (stat_length,) or int is a shortcut for before = after = statistic
    length for all axes.

    Default is ``None``, to use the entire axis.
constant_values : sequence or int, optional
    Used in 'constant'.  The values to set the padded values for each
    axis.

    ((before_1, after_1), ... (before_N, after_N)) unique pad constants
    for each axis.

    ((before, after),) yields same before and after constants for each
    axis.

    (constant,) or int is a shortcut for before = after = constant for
    all axes.

    Default is 0.
end_values : sequence or int, optional
    Used in 'linear_ramp'.  The values used for the ending value of the
    linear_ramp and that will form the edge of the padded array.

    ((before_1, after_1), ... (before_N, after_N)) unique end values
    for each axis.

    ((before, after),) yields same before and after end values for each
    axis.

    (constant,) or int is a shortcut for before = after = end value for
    all axes.

    Default is 0.
reflect_type : {'even', 'odd'}, optional
    Used in 'reflect', and 'symmetric'.  The 'even' style is the
    default with an unaltered reflection around the edge value.  For
    the 'odd' style, the extented part of the array is created by
    subtracting the reflected values from two times the edge value.

Returns
-------
pad : ndarray
    Padded array of rank equal to `array` with shape increased
    according to `pad_width`.

Notes
-----
.. versionadded:: 1.7.0

For an array with rank greater than 1, some of the padding of later
axes is calculated from padding of previous axes.  This is easiest to
think about with a rank 2 array where the corners of the padded array
are calculated by using padded values from the first axis.

The padding function, if used, should return a rank 1 array equal in
length to the vector argument with padded values replaced. It has the
following signature::

    padding_func(vector, iaxis_pad_width, iaxis, kwargs)

where

    vector : ndarray
        A rank 1 array already padded with zeros.  Padded values are
        vector[:pad_tuple[0]] and vector[-pad_tuple[1]:].
    iaxis_pad_width : tuple
        A 2-tuple of ints, iaxis_pad_width[0] represents the number of
        values padded at the beginning of vector where
        iaxis_pad_width[1] represents the number of values padded at
        the end of vector.
    iaxis : int
        The axis currently being calculated.
    kwargs : dict
        Any keyword arguments the function requires.

Examples
--------
>>> a = [1, 2, 3, 4, 5]
>>> np.pad(a, (2,3), 'constant', constant_values=(4, 6))
array([4, 4, 1, 2, 3, 4, 5, 6, 6, 6])

>>> np.pad(a, (2, 3), 'edge')
array([1, 1, 1, 2, 3, 4, 5, 5, 5, 5])

>>> np.pad(a, (2, 3), 'linear_ramp', end_values=(5, -4))
array([ 5,  3,  1,  2,  3,  4,  5,  2, -1, -4])

>>> np.pad(a, (2,), 'maximum')
array([5, 5, 1, 2, 3, 4, 5, 5, 5])

>>> np.pad(a, (2,), 'mean')
array([3, 3, 1, 2, 3, 4, 5, 3, 3])

>>> np.pad(a, (2,), 'median')
array([3, 3, 1, 2, 3, 4, 5, 3, 3])

>>> a = [[1, 2], [3, 4]]
>>> np.pad(a, ((3, 2), (2, 3)), 'minimum')
array([[1, 1, 1, 2, 1, 1, 1],
       [1, 1, 1, 2, 1, 1, 1],
       [1, 1, 1, 2, 1, 1, 1],
       [1, 1, 1, 2, 1, 1, 1],
       [3, 3, 3, 4, 3, 3, 3],
       [1, 1, 1, 2, 1, 1, 1],
       [1, 1, 1, 2, 1, 1, 1]])

>>> a = [1, 2, 3, 4, 5]
>>> np.pad(a, (2, 3), 'reflect')
array([3, 2, 1, 2, 3, 4, 5, 4, 3, 2])

>>> np.pad(a, (2, 3), 'reflect', reflect_type='odd')
array([-1,  0,  1,  2,  3,  4,  5,  6,  7,  8])

>>> np.pad(a, (2, 3), 'symmetric')
array([2, 1, 1, 2, 3, 4, 5, 5, 4, 3])

>>> np.pad(a, (2, 3), 'symmetric', reflect_type='odd')
array([0, 1, 1, 2, 3, 4, 5, 5, 6, 7])

>>> np.pad(a, (2, 3), 'wrap')
array([4, 5, 1, 2, 3, 4, 5, 1, 2, 3])

>>> def pad_with(vector, pad_width, iaxis, kwargs):
...     pad_value = kwargs.get('padder', 10)
...     vector[:pad_width[0]] = pad_value
...     vector[-pad_width[1]:] = pad_value
...     return vector
>>> a = np.arange(6)
>>> a = a.reshape((2, 3))
>>> np.pad(a, 2, pad_with)
array([[10, 10, 10, 10, 10, 10, 10],
       [10, 10, 10, 10, 10, 10, 10],
       [10, 10,  0,  1,  2, 10, 10],
       [10, 10,  3,  4,  5, 10, 10],
       [10, 10, 10, 10, 10, 10, 10],
       [10, 10, 10, 10, 10, 10, 10]])
>>> np.pad(a, 2, pad_with, padder=100)
array([[100, 100, 100, 100, 100, 100, 100],
       [100, 100, 100, 100, 100, 100, 100],
       [100, 100,   0,   1,   2, 100, 100],
       [100, 100,   3,   4,   5, 100, 100],
       [100, 100, 100, 100, 100, 100, 100],
       [100, 100, 100, 100, 100, 100, 100]])
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.