팬더 데이터 프레임을 NumPy 배열로 변환


465

팬더 데이터 프레임을 NumPy 배열로 변환하는 방법을 알고 싶습니다.

데이터 프레임 :

import numpy as np
import pandas as pd

index = [1, 2, 3, 4, 5, 6, 7]
a = [np.nan, np.nan, np.nan, 0.1, 0.1, 0.1, 0.1]
b = [0.2, np.nan, 0.2, 0.2, 0.2, np.nan, np.nan]
c = [np.nan, 0.5, 0.5, np.nan, 0.5, 0.5, np.nan]
df = pd.DataFrame({'A': a, 'B': b, 'C': c}, index=index)
df = df.rename_axis('ID')

준다

label   A    B    C
ID                                 
1   NaN  0.2  NaN
2   NaN  NaN  0.5
3   NaN  0.2  0.5
4   0.1  0.2  NaN
5   0.1  0.2  0.5
6   0.1  NaN  0.5
7   0.1  NaN  NaN

이것을 NumPy 배열로 변환하고 싶습니다.

array([[ nan,  0.2,  nan],
       [ nan,  nan,  0.5],
       [ nan,  0.2,  0.5],
       [ 0.1,  0.2,  nan],
       [ 0.1,  0.2,  0.5],
       [ 0.1,  nan,  0.5],
       [ 0.1,  nan,  nan]])

어떻게해야합니까?


보너스로, dtype을 이와 같이 보존 할 수 있습니까?

array([[ 1, nan,  0.2,  nan],
       [ 2, nan,  nan,  0.5],
       [ 3, nan,  0.2,  0.5],
       [ 4, 0.1,  0.2,  nan],
       [ 5, 0.1,  0.2,  0.5],
       [ 6, 0.1,  nan,  0.5],
       [ 7, 0.1,  nan,  nan]],
     dtype=[('ID', '<i4'), ('A', '<f8'), ('B', '<f8'), ('B', '<f8')])

아니면 비슷한?


5
왜 이것이 필요합니까? 어쨌든 numpy 배열을 기반으로하는 데이터 프레임이 아닙니까? numpy 배열이 필요한 데이터 프레임을 사용할 수 있어야합니다. 그렇기 때문에 함수가 numpy 배열을 요구하는 scikit-learn과 함께 데이터 프레임을 사용할 수 있습니다.
chrisfs

다음은 dtypes 및 recarrays (일명 레코드 배열 또는 구조적 배열)에 대한 관련 링크입니다. (1) stackoverflow.com/questions/9949427/… (2) stackoverflow.com/questions/52579601/…
JohnE

참고 : 이와 같이 Pandas DataFrame을 배열 (또는 목록)로 변환해야하는 것은 다른 문제를 나타낼 수 있습니다. DataFrame이 특정 사용 사례에 적합한 데이터 구조이고 Pandas에 관심있는 작업을 수행하는 방법이 포함되어 있지 않도록하는 것이 좋습니다.
AMC

답변:


391

팬더 데이터 프레임 (df)을 numpy ndarray로 변환하려면 다음 코드를 사용하십시오.

df.values

array([[nan, 0.2, nan],
       [nan, nan, 0.5],
       [nan, 0.2, 0.5],
       [0.1, 0.2, nan],
       [0.1, 0.2, 0.5],
       [0.1, nan, 0.5],
       [0.1, nan, nan]])

238

values및 의 사용법을 더 이상 사용하지 마십시오 as_matrix()!

pandas v0.24.0에는 pandas 객체에서 NumPy 배열을 얻는 두 가지 새로운 방법이 도입되었습니다.

  1. to_numpy()에 정의 된 Index, Series,그리고 DataFrame개체 및
  2. array, IndexSeries객체에만 정의되어 있습니다.

에 대한 v0.24 문서를 방문하면 다음과 .values같은 큰 빨간색 경고가 표시됩니다.

경고 : DataFrame.to_numpy()대신 사용 하는 것이 좋습니다 .

참조 v0.24.0 릴리스 노트의이 섹션 , 그리고 이 답변 자세한 정보를.


더 나은 일관성으로 : to_numpy()

API 전체의 일관성을 to_numpy높이기 위해 DataFrames에서 기본 NumPy 배열을 추출 하는 새로운 방법 이 도입되었습니다.

# Setup.
df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]}, index=['a', 'b', 'c'])

df.to_numpy()
array([[1, 4],
       [2, 5],
       [3, 6]])

위에서 언급했듯이이 방법은 객체 IndexSeries객체 에도 정의되어 있습니다 ( 여기 참조 ).

df.index.to_numpy()
# array(['a', 'b', 'c'], dtype=object)

df['A'].to_numpy()
#  array([1, 2, 3])

기본적으로보기가 반환되므로 수정 한 내용이 원본에 영향을줍니다.

v = df.to_numpy()
v[0, 0] = -1

df
   A  B
a -1  4
b  2  5
c  3  6

대신 사본이 필요한 경우)를 사용 to_numpy(copy=True하십시오.

ExtensionTypes의 팬더> = 1.0 업데이트

pandas 1.x를 사용하는 경우 확장 유형을 훨씬 더 많이 다루게 될 것입니다. 이러한 확장 유형이 올바르게 변환되도록 좀 더 조심해야합니다.

a = pd.array([1, 2, None], dtype="Int64")                                  
a                                                                          

<IntegerArray>
[1, 2, <NA>]
Length: 3, dtype: Int64 

# Wrong
a.to_numpy()                                                               
# array([1, 2, <NA>], dtype=object)  # yuck, objects

# Right
a.to_numpy(dtype='float', na_value=np.nan)                                 
# array([ 1.,  2., nan])

이것은 문서에서 호출됩니다 .

필요한 경우 dtypes...

다른 답변에서 볼 수 있듯이이 DataFrame.to_records작업을 수행하는 좋은 방법입니다.

df.to_records()
# rec.array([('a', -1, 4), ('b',  2, 5), ('c',  3, 6)],
#           dtype=[('index', 'O'), ('A', '<i8'), ('B', '<i8')])

to_numpy불행히도이 작업은 수행 할 수 없습니다 . 그러나 대안으로 다음을 사용할 수 있습니다 np.rec.fromrecords.

v = df.reset_index()
np.rec.fromrecords(v, names=v.columns.tolist())
# rec.array([('a', -1, 4), ('b',  2, 5), ('c',  3, 6)],
#          dtype=[('index', '<U1'), ('A', '<i8'), ('B', '<i8')])

성능면에서는 거의 동일합니다 (실제로 사용하는 rec.fromrecords것이 약간 빠릅니다).

df2 = pd.concat([df] * 10000)

%timeit df2.to_records()
%%timeit
v = df2.reset_index()
np.rec.fromrecords(v, names=v.columns.tolist())

11.1 ms ± 557 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
9.67 ms ± 126 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

새로운 방법을 추가하는 근거

to_numpy()array두 개의 GitHub 이슈 GH19954GH23623 에 대한 토론의 결과로 (와 함께 )가 추가되었습니다 .

특히 문서는 이론적 근거를 언급합니다.

[...] .values반환 값이 실제 배열인지, 일부 변환인지, pandas 사용자 정의 배열 중 하나 (예 :)인지 확실하지 않았습니다 Categorical. 예를 들어 with PeriodIndex.values 사용하면 ndarray매번 새로운 기간 객체가 생성 됩니다. [...]

to_numpy올바른 방향의 주요 단계 인 API의 일관성을 향상시키는 것을 목표로합니다. .values현재 버전에서는 더 이상 사용되지 않지만 향후 어느 시점에서 이러한 상황이 발생할 수 있으므로 가능한 한 빨리 새로운 API로 사용자를 마이그레이션하도록 촉구합니다.


다른 솔루션의 비판

DataFrame.values 이미 언급했듯이 행동이 일치하지 않습니다.

DataFrame.get_values()는 단순히 래퍼 DataFrame.values이므로 위에서 언급 한 모든 것이 적용됩니다.

DataFrame.as_matrix()더 이상 사용되지 않습니다. 사용 하지 마십시오 !


나는 폐의 상단에 비명을 지르는 사람들의 페이지를 넘은 후 페이지를 읽고 어떻게 as_matrix다른 솔루션 으로 전환 할 수 있는지 이해하지 못합니다 .이 경우 to_numpy열 선택 기능을 복구하는 방법을 설명하지 않습니다 as_matrix. 열을 선택하는 다른 방법이 있다고 확신하지만 as_matrix그 중 하나 이상이었습니다!
Jérémie

명백한 것 외에 @ Jérémie df[[col1, col2']].to_numpy()? 더 이상 사용되지 않는 기능에 대한 업데이트 된 대안을 광고하려고한다고 생각하는 이유는 확실하지 않습니다.
cs95

열 중 일부가 목록 유형 인 경우 이로부터 평평한 울퉁불퉁 한 배열을 어떻게 만들 수 있습니까?
Moniba

@Moniba 먼저 요구 사항에 따라 목록 항목을 별도의 열 / 행으로 분해 할 수 있습니다.
cs95

내가 틀리지 않는 한, 같은 호출에서 둘 이상의 열을 가져 오면 모든 데이터가 하나의 큰 배열로 병합됩니다. 뭔가 빠졌습니까?
Andrea Moro

128

참고 : .as_matrix()이 답변에 사용 된 방법은 더 이상 사용되지 않습니다. 팬더 0.23.4 경고 :

.as_matrix향후 버전에서는 메소드 가 제거 될 예정입니다. .values를 대신 사용하십시오.


팬더에는 무언가가 내장되어 있습니다 ...

numpy_matrix = df.as_matrix()

준다

array([[nan, 0.2, nan],
       [nan, nan, 0.5],
       [nan, 0.2, 0.5],
       [0.1, 0.2, nan],
       [0.1, 0.2, 0.5],
       [0.1, nan, 0.5],
       [0.1, nan, nan]])

30
이것은 구조적 배열을 제공하지 않으며 모든 열은 dtype object입니다.
sebix

14
"버전 0.23.0부터 사용되지 않습니다. 대신 DataFrame.values를 사용하십시오." / "이 방법은 이전 버전과의 호환성을 위해 제공됩니다. 일반적으로 '.values'를 사용하는 것이 좋습니다." - github.com/pandas-dev/pandas/blob/...
데이비드 J.

4
이것은 더 이상 사용되지 않습니다. v0.24부터는 to_numpy대신 사용하십시오 .values. 여기 더 .
cs95

1
"FutureWarning : .as_matrix 메서드는 다음 버전에서 제거 될 예정입니다. 대신 .values를 사용하십시오."
Farhad Maleki

66

나는 체인 단지 것 DataFrame.reset_index ()DataFrame.values의 인덱스를 포함하여 dataframe의 NumPy와 표현을 얻을 기능 :

In [8]: df
Out[8]: 
          A         B         C
0 -0.982726  0.150726  0.691625
1  0.617297 -0.471879  0.505547
2  0.417123 -1.356803 -1.013499
3 -0.166363 -0.957758  1.178659
4 -0.164103  0.074516 -0.674325
5 -0.340169 -0.293698  1.231791
6 -1.062825  0.556273  1.508058
7  0.959610  0.247539  0.091333

[8 rows x 3 columns]

In [9]: df.reset_index().values
Out[9]:
array([[ 0.        , -0.98272574,  0.150726  ,  0.69162512],
       [ 1.        ,  0.61729734, -0.47187926,  0.50554728],
       [ 2.        ,  0.4171228 , -1.35680324, -1.01349922],
       [ 3.        , -0.16636303, -0.95775849,  1.17865945],
       [ 4.        , -0.16410334,  0.0745164 , -0.67432474],
       [ 5.        , -0.34016865, -0.29369841,  1.23179064],
       [ 6.        , -1.06282542,  0.55627285,  1.50805754],
       [ 7.        ,  0.95961001,  0.24753911,  0.09133339]])

dtype을 얻으려면 view를 사용 하여이 ndarray를 구조적 배열로 변환해야합니다 .

In [10]: df.reset_index().values.ravel().view(dtype=[('index', int), ('A', float), ('B', float), ('C', float)])
Out[10]:
array([( 0, -0.98272574,  0.150726  ,  0.69162512),
       ( 1,  0.61729734, -0.47187926,  0.50554728),
       ( 2,  0.4171228 , -1.35680324, -1.01349922),
       ( 3, -0.16636303, -0.95775849,  1.17865945),
       ( 4, -0.16410334,  0.0745164 , -0.67432474),
       ( 5, -0.34016865, -0.29369841,  1.23179064),
       ( 6, -1.06282542,  0.55627285,  1.50805754),
       ( 7,  0.95961001,  0.24753911,  0.09133339),
       dtype=[('index', '<i8'), ('A', '<f8'), ('B', '<f8'), ('C', '<f8')])

3
이 답변에서 빠진 것은 데이터 프레임에서 dtype을 구성하여 일반적인 함수를 작성할 수있는 방법입니다.
Joseph Garvin

32

to_records방법을 사용할 수는 있지만 원하는 방식이 아닌 경우 dtypes를 사용하여 조금 놀아야합니다. 필자의 경우 DF를 문자열에서 복사하면 인덱스 유형은 문자열입니다 ( object팬더 에서 dtype으로 표시 ).

In [102]: df
Out[102]: 
label    A    B    C
ID                  
1      NaN  0.2  NaN
2      NaN  NaN  0.5
3      NaN  0.2  0.5
4      0.1  0.2  NaN
5      0.1  0.2  0.5
6      0.1  NaN  0.5
7      0.1  NaN  NaN

In [103]: df.index.dtype
Out[103]: dtype('object')
In [104]: df.to_records()
Out[104]: 
rec.array([(1, nan, 0.2, nan), (2, nan, nan, 0.5), (3, nan, 0.2, 0.5),
       (4, 0.1, 0.2, nan), (5, 0.1, 0.2, 0.5), (6, 0.1, nan, 0.5),
       (7, 0.1, nan, nan)], 
      dtype=[('index', '|O8'), ('A', '<f8'), ('B', '<f8'), ('C', '<f8')])
In [106]: df.to_records().dtype
Out[106]: dtype([('index', '|O8'), ('A', '<f8'), ('B', '<f8'), ('C', '<f8')])

recarray dtype을 변환해도 효과가 없지만 Pandas에서 이미이 작업을 수행 할 수 있습니다.

In [109]: df.index = df.index.astype('i8')
In [111]: df.to_records().view([('ID', '<i8'), ('A', '<f8'), ('B', '<f8'), ('C', '<f8')])
Out[111]:
rec.array([(1, nan, 0.2, nan), (2, nan, nan, 0.5), (3, nan, 0.2, 0.5),
       (4, 0.1, 0.2, nan), (5, 0.1, 0.2, 0.5), (6, 0.1, nan, 0.5),
       (7, 0.1, nan, nan)], 
      dtype=[('ID', '<i8'), ('A', '<f8'), ('B', '<f8'), ('C', '<f8')])

Pandas는 ID내 보낸 레코드 배열에서 버그 의 이름을 (to ) 올바르게 설정하지 않았으므로 (버그?) 형식 변환을 통해이를 수정합니다.

현재 Pandas에는 8 바이트 정수 i8및 부동 소수점 만 있습니다 f8(이 문제 참조 ).


2
원하는 구조화 된 배열 (recarray보다 성능이 더 좋은)을 얻으려면 recarray를 np.array생성자에 전달하면 됩니다.
meteore

우리는 위에 표시된 색인의 이름을 설정하기위한 수정을했습니다.
Chang She

26

df.to_records()당신에게 도움이 될 것 같습니다 . 당신이 찾고있는 정확한 기능 이 요청 되었고 to_records대안으로 지적되었습니다.

나는 당신의 예제를 사용하여 이것을 로컬로 시도했고, 그 호출은 당신이 찾고있는 출력과 매우 비슷한 것을 산출합니다 :

rec.array([(1, nan, 0.2, nan), (2, nan, nan, 0.5), (3, nan, 0.2, 0.5),
       (4, 0.1, 0.2, nan), (5, 0.1, 0.2, 0.5), (6, 0.1, nan, 0.5),
       (7, 0.1, nan, nan)],
      dtype=[(u'ID', '<i8'), (u'A', '<f8'), (u'B', '<f8'), (u'C', '<f8')])

이것은 유의 recarray보다는를 array. 생성자를로 호출하여 결과를 일반 numpy 배열로 이동할 수 있습니다 np.array(df.to_records()).


3
잠깐,이 답변 to_records()은 5 년 전에 언급 한 @meteore의 다른 답변과 비교하여 무엇을 추가 합니까?
JohnE

13

이 시도:

a = numpy.asarray(df)

안녕! 답변에 설명을 추가하십시오. 현재 길이내용 으로 인해 리뷰에서 품질이 낮은 것으로 표시 되고 있으며 시스템에서 삭제 될 위험이 있습니다. 감사!
d_kennetz 17 년

1
기본적으로 입력 이름을 배열로 변환하십시오 (이름에서 알 수 있듯이). 따라서 질문의 맥락과 함께이 답변은 유효합니다. docs.scipy.org/doc/numpy/reference/generated/…
Lautaro Parada Opazo

고마워, 나는 그것이 자명하다고 생각합니다.
Dadu Khan

8

다음은 팬더 DataFrame에서 구조 배열을 만드는 방법입니다.

데이터 프레임 생성

import pandas as pd
import numpy as np
import six

NaN = float('nan')
ID = [1, 2, 3, 4, 5, 6, 7]
A = [NaN, NaN, NaN, 0.1, 0.1, 0.1, 0.1]
B = [0.2, NaN, 0.2, 0.2, 0.2, NaN, NaN]
C = [NaN, 0.5, 0.5, NaN, 0.5, 0.5, NaN]
columns = {'A':A, 'B':B, 'C':C}
df = pd.DataFrame(columns, index=ID)
df.index.name = 'ID'
print(df)

      A    B    C
ID               
1   NaN  0.2  NaN
2   NaN  NaN  0.5
3   NaN  0.2  0.5
4   0.1  0.2  NaN
5   0.1  0.2  0.5
6   0.1  NaN  0.5
7   0.1  NaN  NaN

팬더 DataFrame에서 레코드 배열이 아닌 numpy 구조 배열을 만드는 함수를 정의하십시오.

def df_to_sarray(df):
    """
    Convert a pandas DataFrame object to a numpy structured array.
    This is functionally equivalent to but more efficient than
    np.array(df.to_array())

    :param df: the data frame to convert
    :return: a numpy structured array representation of df
    """

    v = df.values
    cols = df.columns

    if six.PY2:  # python 2 needs .encode() but 3 does not
        types = [(cols[i].encode(), df[k].dtype.type) for (i, k) in enumerate(cols)]
    else:
        types = [(cols[i], df[k].dtype.type) for (i, k) in enumerate(cols)]
    dtype = np.dtype(types)
    z = np.zeros(v.shape[0], dtype)
    for (i, k) in enumerate(z.dtype.names):
        z[k] = v[:, i]
    return z

reset_index인덱스를 데이터의 일부로 포함하는 새 데이터 프레임을 만드는 데 사용 합니다. 해당 데이터 프레임을 구조 배열로 변환하십시오.

sa = df_to_sarray(df.reset_index())
sa

array([(1L, nan, 0.2, nan), (2L, nan, nan, 0.5), (3L, nan, 0.2, 0.5),
       (4L, 0.1, 0.2, nan), (5L, 0.1, 0.2, 0.5), (6L, 0.1, nan, 0.5),
       (7L, 0.1, nan, nan)], 
      dtype=[('ID', '<i8'), ('A', '<f8'), ('B', '<f8'), ('C', '<f8')])

편집 : 파이썬 3. 감사와 피할 오류 호출 함수 .encode ()에 업데이트 df_to_sarray 조셉 가빈평온한 자신의 의견과 솔루션.


나를 위해 작동하지 않습니다, 오류 : TypeError : 데이터 형식을 이해할 수 없습니다
Joseph Garvin

귀하의 의견 및 덕분에 평온한 보정합니다. 내 답변을 업데이트 했으므로 지금 효과가 있기를 바랍니다.
Phil


5

DataFrame 예제를위한 간단한 방법 :

df

         gbm       nnet        reg
0  12.097439  12.047437  12.100953
1  12.109811  12.070209  12.095288
2  11.720734  11.622139  11.740523
3  11.824557  11.926414  11.926527
4  11.800868  11.727730  11.729737
5  12.490984  12.502440  12.530894

사용하다:

np.array(df.to_records().view(type=np.matrix))

가져 오기:

array([[(0, 12.097439  , 12.047437, 12.10095324),
        (1, 12.10981081, 12.070209, 12.09528824),
        (2, 11.72073428, 11.622139, 11.74052253),
        (3, 11.82455653, 11.926414, 11.92652727),
        (4, 11.80086775, 11.72773 , 11.72973699),
        (5, 12.49098389, 12.50244 , 12.53089367)]],
dtype=(numpy.record, [('index', '<i8'), ('gbm', '<f8'), ('nnet', '<f4'),
       ('reg', '<f8')]))

4

데이터 프레임에서 arcgis 테이블로 내보낼 때 비슷한 문제가 있었고 usgs의 솔루션을 우연히 발견했습니다 ( https://my.usgs.gov/confluence/display/cdi/pandas.DataFrame+to+ArcGIS+Table ). 요컨대 문제는 비슷한 해결책을 가지고 있습니다.

df

      A    B    C
ID               
1   NaN  0.2  NaN
2   NaN  NaN  0.5
3   NaN  0.2  0.5
4   0.1  0.2  NaN
5   0.1  0.2  0.5
6   0.1  NaN  0.5
7   0.1  NaN  NaN

np_data = np.array(np.rec.fromrecords(df.values))
np_names = df.dtypes.index.tolist()
np_data.dtype.names = tuple([name.encode('UTF8') for name in np_names])

np_data

array([( nan,  0.2,  nan), ( nan,  nan,  0.5), ( nan,  0.2,  0.5),
       ( 0.1,  0.2,  nan), ( 0.1,  0.2,  0.5), ( 0.1,  nan,  0.5),
       ( 0.1,  nan,  nan)], 
      dtype=(numpy.record, [('A', '<f8'), ('B', '<f8'), ('C', '<f8')]))

4

위의 답변을 살펴 보았습니다. " as_matrix () "메소드는 작동하지만 더 이상 사용되지 않습니다. 나를 위해 일한 것은 " .to_numpy () "였습니다.

다차원 배열을 반환합니다. Excel 시트에서 데이터를 읽고 인덱스에서 데이터에 액세스 해야하는 경우이 방법을 사용하는 것이 좋습니다. 도움이 되었기를 바랍니다 :)


무엇을 의미하며 어떤 인덱스에서 데이터에 액세스해야 합니까? 데이터의 특성에 따라 Pandas DataFrame이 처음에는 올바른 선택이 아닐 수도 있습니다.
AMC

2

유성의 답변에 더하여 코드를 찾았습니다.

df.index = df.index.astype('i8')

나를 위해 작동하지 않습니다. 그래서이 문제로 다른 사람들의 편의를 위해 코드를 여기에 넣었습니다.

city_cluster_df = pd.read_csv(text_filepath, encoding='utf-8')
# the field 'city_en' is a string, when converted to Numpy array, it will be an object
city_cluster_arr = city_cluster_df[['city_en','lat','lon','cluster','cluster_filtered']].to_records()
descr=city_cluster_arr.dtype.descr
# change the field 'city_en' to string type (the index for 'city_en' here is 1 because before the field is the row index of dataframe)
descr[1]=(descr[1][0], "S20")
newArr=city_cluster_arr.astype(np.dtype(descr))

1

데이터 프레임을 numpy 배열로 변환하는 간단한 방법 :

import pandas as pd
df = pd.DataFrame({"A": [1, 2], "B": [3, 4]})
df_to_array = df.to_numpy()
array([[1, 3],
   [2, 4]])

일관성을 유지하기 위해 to_numpy를 사용하는 것이 좋습니다.

참조 : https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.to_numpy.html


Arsam과 귀하의 솔루션의 차이점은 무엇입니까?
qaiser

내가 개인적으로 선호하는 코드 예제를 사용하여 더 완벽하고 유용하게 만들려고했습니다.
user1460675

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.