NumPy 또는 Pandas : NaN 값을 갖는 동안 배열 유형을 정수로 유지


160

내부에 요소를 계속 나열하면서 numpy배열 의 데이터 유형을 고정 int( int64또는 기타) 으로 유지하는 선호되는 방법이 numpy.NaN있습니까?

특히, 사내 데이터 구조를 Pandas DataFrame으로 변환하고 있습니다. 우리의 구조에는 여전히 NaN을 가진 정수형 열이 있지만 열의 dtype은 int입니다. 이것을 DataFrame으로 만들면 모든 것을 float로 다시 캐스팅하는 것처럼 보이지만 실제로는되고 싶습니다 int.

생각?

시도한 것 :

from_records()pandas.DataFrame 에서 함수를 사용해 보았지만 coerce_float=False도움이되지 않았습니다. 또한 NaN fill_value와 함께 NumPy 마스크 배열을 사용해 보았습니다. 이로 인해 열 데이터 유형이 부동이되었습니다.


numpy masked array를 사용할 수 있습니까?
mgilson

시도해 볼게요. 또한 from_recordspandas.DataFrame 에서 함수를 사용해 보았지만 coerce_float=False운이 없습니다 ... 여전히 새 데이터에 유형이 float64있습니다.
ely

1
그래, 운이 없어 마스크 배열을 사용하더라도 여전히 float로 변환됩니다. 팬더가 다음과 같이 보이는 것처럼 보입니다. "NaN이 있습니까? ... 그렇다면 모든 것이 플로트입니다." 잘하면이 주위에 방법이 있습니다.
ely

1
선택적 Nullable Integer Support가 공식적으로 pandas 0.24.0에 추가되었습니다-마지막으로 :)-업데이트 된 답변을 찾으십시오. pandas 0.24.x 출시 노트
mork

답변:


70

이 기능은 팬더에 추가되었습니다 (버전 0.24부터 시작) : https://pandas.pydata.org/pandas-docs/version/0.24/whatsnew/v0.24.0.html#optional-integer-na-support

이때 기본 dtype int64 (소문자) 대신 확장 dtype Int64 (대문자)를 사용해야합니다.


1
지금은 특수 dtype을 지정 'Int64'해야 작동합니다. 기본적으로 활성화되면 더 좋습니다.
Jean Paul

대단해! PyCharm이 이런 식으로 사용되는 경우 디버그 창에 데이터 프레임을 표시하지 못하는 작은 문제가 있습니다. 당신은 어떻게 표시 강제로에 대한 다른 질문에 대한 내 대답을 볼 수 stackoverflow.com/questions/38956660/...를 (원래 문제가 다르지만 dataframe 작동 표시하기위한 솔루션)
알라 M.

내가 사용해야 합니까 아니면 'Int64'같은 것이 'Int8'있습니까? 에 비해 엄청난 양의 메모리를 사용합니다 np.float.
Superdooperhero 2018 년

'Int8'작동하는 것처럼 보이지만 np.float여전히 더 빨리로드되는 것 같습니다. 문제는 메모리를 해제하지 않는 것 같습니다. 가비지 수집기가 결국 실행된다고 가정합니다.
Superdooperhero 2018 년

103

NaN정수 배열에 저장할 수 없습니다. 이것은 현재 판다의 알려진 제한 사항입니다. NumPy의 NA 값 (R의 NA와 비슷한)으로 진행이 진행되기를 기다리고 있지만 NumPy가 이러한 기능을 얻는 데는 적어도 6 개월에서 1 년이 걸릴 것 같습니다.

http://pandas.pydata.org/pandas-docs/stable/gotchas.html#support-for-integer-na

(이 기능은 팬더 0.24 버전부터 추가되었지만 기본 dtype int64 (소문자)가 아닌 확장 dtype Int64 (대문자)를 사용해야합니다. https://pandas.pydata.org/pandas- docs / version / 0.24 / whatsnew / v0.24.0.html # optional-integer-na-support )


7
안녕 웨스, 이것에 대한 업데이트가 있습니까? 조인 열이 원래 목록에 NA 값이 있는지에 따라 int 또는 float로 변환되는 문제가 발생합니다. (이 데이터 프레임을 병합하려고 할 때 나중에 문제 생성)
Carst


8

성능이 주요 문제가 아닌 경우 대신 문자열을 저장할 수 있습니다.

df.col = df.col.dropna().apply(lambda x: str(int(x)) )

그런 다음 NaN원하는만큼 혼합 할 수 있습니다 . 실제로 응용 프로그램에 따라 정수를 원한다면 -1, 또는 0, 또는 1234567890, 또는 다른 전용 값을 사용하여 나타낼 수 NaN있습니다.

열을 임시로 복제 할 수도 있습니다. 다른 하나는 int 또는 string을 사용하여 실험합니다. 그런 다음 asserts모든 적절한 장소에 삽입 하여 두 가지가 동기화되었는지 확인하십시오. 충분한 테스트가 끝나면 수레를 놓을 수 있습니다.


5

이것은 모든 경우에 대한 해결책은 아니지만 내 (게놈 좌표) 0을 NaN으로 사용하기로 결정했습니다.

a3['MapInfo'] = a3['MapInfo'].fillna(0).astype(int)

이것은 적어도 적절한 '네이티브'컬럼 유형을 사용할 수있게하고 빼기, 비교 등과 같은 연산이 예상대로 작동합니다.


5

팬더 v0.24 +

NaN정수 시리즈에서 지원 하는 기능 은 v0.24 이상에서 사용할 수 있습니다. 있어 이에 대한 정보 섹션, 이하 자세한 내용은 "새로운 기능"를 v0.24에서 null 허용 정수 데이터 유형 .

팬더 v0.23 및 이전

일반적으로, 함께 작동하도록 최선의 float시리즈가에서 업 캐스팅에도 가능, 시리즈 intfloat인해의 포함에 NaN값. 이를 통해 파이썬 레벨 루프가 처리되는 벡터화 된 NumPy 기반 계산이 가능합니다.

문서는 제안합니다 : "하나의 가능성은 dtype=object배열을 대신 사용하는 것입니다." 예를 들면 다음과 같습니다.

s = pd.Series([1, 2, 3, np.nan])

print(s.astype(object))

0      1
1      2
2      3
3    NaN
dtype: object

외관상의 이유로, 예를 들어 파일로 출력하는 것이 바람직 할 수 있습니다.

팬더 v0.23 및 이전 : 배경

NaN로 간주됩니다float . (v0.23 기준) 현재 문서 정수 시리즈에 upcasted하는 이유를 지정합니다 float:

고성능 NA 지원이 처음부터 NumPy에 내장되어 있지 않은 경우, 주요 사상자는 정수 배열로 NA를 표현하는 능력입니다.

이 절충은 주로 메모리와 성능상의 이유로 만들어지며 결과 시리즈는 계속 "숫자"가됩니다.

문서는 포함 으로 인한 업 캐스팅 규칙제공합니다NaN .

Typeclass   Promotion dtype for storing NAs
floating    no change
object      no change
integer     cast to float64
boolean     cast to object


1

NA를 새로운 'Int64'dtype으로 변환하는 float (1.143) 벡터를 정수 (1)로 변환하려고하면 오류가 발생한다는 것을 추가하고 싶었습니다. 이 문제를 해결하려면 숫자를 반올림 한 다음 ".astype ( 'Int64')"를 수행해야합니다.

s1 = pd.Series([1.434, 2.343, np.nan])
#without round() the next line returns an error 
s1.astype('Int64')
#cannot safely cast non-equivalent float64 to int64
##with round() it works
s1.round().astype('Int64')
0      1
1      2
2    NaN
dtype: Int64

내 유스 케이스는 int로 반올림하려는 float 시리즈를 가지고 있지만 .round () 할 때 숫자 끝에 '* .0'이 남아 있으므로 끝에서 0을 삭제할 수 있습니다 int로 변환


0

텍스트 데이터에 공백이있는 경우 int64 dtype은 null을 처리 할 수 ​​없으므로 일반적으로 정수인 열은 float64 dtype으로 float로 캐스팅됩니다. 공백이있는 파일을 여러 개로드하는 경우 (float64로 끝나고 int64로 끝나지 않는 다른 파일)로드하면 스키마가 일치하지 않을 수 있습니다

Int64는 null을 처리 할 수 ​​있으므로이 코드는 모든 숫자 유형 열을 int64와 반대로 Int64로 변환하려고 시도합니다.

import pandas as pd
import numpy as np

#show datatypes before transformation
mydf.dtypes

for c in mydf.select_dtypes(np.number).columns:
    try:
        mydf[c] = mydf[c].astype('Int64')
        print('casted {} as Int64'.format(c))
    except:
        print('could not cast {} to Int64'.format(c))

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