팬더 데이터 프레임을 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')])
아니면 비슷한?
답변
팬더 데이터 프레임 (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]])
답변
values
및 의 사용법을 더 이상 사용하지 마십시오 as_matrix()
!
pandas v0.24.0에는 pandas 객체에서 NumPy 배열을 얻는 두 가지 새로운 방법이 도입되었습니다.
to_numpy()
에 정의 된Index
,Series,
그리고DataFrame
개체 및array
,Index
및Series
객체에만 정의되어 있습니다.
에 대한 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]])
위에서 언급했듯이이 방법은 객체 Index
와 Series
객체 에도 정의되어 있습니다 ( 여기 참조 ).
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 이슈 GH19954 및 GH23623 에 대한 토론의 결과로 (와 함께 )가 추가되었습니다 .
특히 문서는 이론적 근거를 언급합니다.
[…]
.values
반환 값이 실제 배열인지, 일부 변환인지, pandas 사용자 정의 배열 중 하나 (예 :)인지 확실하지 않았습니다Categorical
. 예를 들어 withPeriodIndex
를.values
사용하면ndarray
매번 새로운 기간 객체가 생성 됩니다. […]
to_numpy
올바른 방향의 주요 단계 인 API의 일관성을 향상시키는 것을 목표로합니다. .values
현재 버전에서는 더 이상 사용되지 않지만 향후 어느 시점에서 이러한 상황이 발생할 수 있으므로 가능한 한 빨리 새로운 API로 사용자를 마이그레이션하도록 촉구합니다.
다른 솔루션의 비판
DataFrame.values
이미 언급했듯이 행동이 일치하지 않습니다.
DataFrame.get_values()
는 단순히 래퍼 DataFrame.values
이므로 위에서 언급 한 모든 것이 적용됩니다.
DataFrame.as_matrix()
더 이상 사용되지 않습니다. 사용 하지 마십시오 !
답변
참고 : .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]])
답변
나는 체인 단지 것 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')])
답변
이 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
(이 문제 참조 ).
답변
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())
.
답변
이 시도:
a = numpy.asarray(df)