[python] NaN이 포함 된 Pandas 열을 dtype`int`로 변환

아래와 같이 .csv 파일에서 Pandas 데이터 프레임으로 데이터를 읽습니다. 열 중 하나, 즉 id열 유형을로 지정하고 싶습니다 int. 문제는 id시리즈에 누락 된 / 빈 값이 있다는 것입니다.

id.csv를 읽는 동안 열을 정수 로 캐스팅하려고 하면 다음과 같은 결과가 나타납니다.

df= pd.read_csv("data.csv", dtype={'id': int}) 
error: Integer column has NA values

또는 아래와 같이 읽은 후 열 유형을 변환하려고 시도했지만 이번에는 다음과 같이 표시됩니다.

df= pd.read_csv("data.csv") 
df[['id']] = df[['id']].astype(int)
error: Cannot convert NA to integer

이 문제를 어떻게 해결할 수 있습니까?



답변

정수 열에 NaN rep가없는 것은 팬더 “gotcha” 입니다.

일반적인 해결 방법은 플로트를 사용하는 것입니다.


답변

버전 0.24. +에서 팬더는 결 측값이있는 정수 dtype을 보유하는 기능을 얻었습니다.

널 입력 가능 정수 데이터 유형 .

팬더는을 사용하여 값이 누락 된 정수 데이터를 나타낼 수 있습니다 arrays.IntegerArray. 이것은 판다 내에서 구현되는 확장 유형입니다. 정수의 기본 dtype이 아니며 유추되지 않습니다. dtype을 명시 적으로 array()또는에 전달해야합니다 Series.

arr = pd.array([1, 2, np.nan], dtype=pd.Int64Dtype())
pd.Series(arr)

0      1
1      2
2    NaN
dtype: Int64

열을 널 입력 가능 정수로 변환하려면 다음을 사용하십시오.

df['myCol'] = df['myCol'].astype('Int64')


답변

내 유스 케이스는 DB 테이블에로드하기 전에 데이터를 제거하는 것입니다.

df[col] = df[col].fillna(-1)
df[col] = df[col].astype(int)
df[col] = df[col].astype(str)
df[col] = df[col].replace('-1', np.nan)

NaN을 제거하고 int로 변환 한 다음 str로 변환 한 다음 NAN을 다시 삽입하십시오.

예쁘지는 않지만 작업이 완료됩니다!


답변

이제 NaN을 dtype으로 포함하는 팬더 열을 만들 수 있습니다. 이는 팬더 0.24.0 int에 공식적으로 추가 되었기 때문입니다.

pandas 0.24.x 출시 노트
인용문 : ” Pandas는 값이없는 정수 dtype을 보유 할 수있게되었습니다


답변

열에서 정수와 NaN을 절대적으로 결합하려면 ‘object’데이터 유형을 사용할 수 있습니다.

df['col'] = (
    df['col'].fillna(0)
    .astype(int)
    .astype(object)
    .where(df['col'].notnull())
)

이것은 NaN을 정수로 바꾸고 (어떤 것이 중요하지는 않지만) int로 변환하고 객체로 변환 한 다음 NaN을 다시 삽입합니다.


답변

저장된 데이터를 수정할 수있는 경우 센티넬 값을 missing으로 사용하십시오 id. 열 이름으로 유추되는 일반적인 유스 케이스 id는 엄격하게 0보다 큰 정수 0이므로 센티넬 값으로 사용 하여 쓸 수 있습니다.

if row['id']:
   regular_process(row)
else:
   special_process(row)


답변

.dropna()NaN 값으로 행을 삭제해도 괜찮다면 사용할 수 있습니다 .

df = df.dropna(subset=['id'])

또한, 사용 .fillna()하고 .astype()값으로 NaN를 교체하고 INT로 변환합니다.

정수가 큰 CSV 파일을 처리 할 때이 문제가 발생했지만 일부는 누락되었습니다 (NaN). float를 유형으로 사용하는 것은 옵션이 아니 었습니다. 정밀도를 잃을 수도 있기 때문입니다.

내 솔루션은 str을 중간 유형으로 사용하는 것이 었습니다 . 그런 다음 나중에 코드에서 원하는대로 문자열을 int로 변환 할 수 있습니다. NaN을 0으로 교체했지만 원하는 값을 선택할 수 있습니다.

df = pd.read_csv(filename, dtype={'id':str})
df["id"] = df["id"].fillna("0").astype(int)

예를 들어, float가 정밀도를 잃을 수있는 방법의 예는 다음과 같습니다.

s = "12345678901234567890"
f = float(s)
i = int(f)
i2 = int(s)
print (f, i, i2)

그리고 출력은 다음과 같습니다

1.2345678901234567e+19 12345678901234567168 12345678901234567890