Pandas 또는 Numpy Nan을 None으로 대체하여 MysqlDB와 함께 사용


127

MysqlDB를 사용하여 mysql 데이터베이스에 Pandas 데이터 프레임 (또는 numpy 배열을 사용할 수 있음)을 쓰려고합니다. MysqlDB가 'nan'을 이해하지 못하는 것 같고 데이터베이스에서 nan이 필드 목록에 없다는 오류를 표시합니다. 'nan'을 NoneType으로 변환하는 방법을 찾아야합니다.

어떤 아이디어?


2
그것을 반환 할 수있는 당신이 팬더에서 변경할 수있는 설정이 없습니다 None위해 NULL대신은 nan?
Nathan Hinchey

답변:


194

@bogatron이 맞습니다.를 사용할 수 있습니다 where. pandas에서 기본적으로이 작업을 수행 할 수 있다는 점은 주목할 가치가 있습니다.

df1 = df.where(pd.notnull(df), None)

참고 :이의 DTYPE 변경 모든 열 을을 object.

예:

In [1]: df = pd.DataFrame([1, np.nan])

In [2]: df
Out[2]: 
    0
0   1
1 NaN

In [3]: df1 = df.where(pd.notnull(df), None)

In [4]: df1
Out[4]: 
      0
0     1
1  None

참고 : dtype모든 데이터 유형을 허용하도록 DataFrames 를 다시 캐스팅 할 수없는 작업은 astype다음과 같습니다 fillna.

df1 = df.astype(object).replace(np.nan, 'None')

불행히도 이것도 사용하지도 (종료 된) 문제replaceNone볼 수 없습니다 .


제쳐두고, 대부분의 사용 사례에서 NaN을 None으로 바꿀 필요가 없다는 점에 주목할 가치가 있습니다 . 판다에서 NaN과 None의 차이점 에 대한이 질문을 참조하십시오. .

그러나이 특정 경우에는 (적어도이 답변 당시) 그렇게 보입니다.



1
FWIW .. 이것은 또한 열의 dtype을 object로 변경합니다.하지만 상관 없습니다
Jeff

@Jeff 링크 주셔서 감사합니다. 이상하게도 이전에 찾을 수 없었습니다! None을 허용하기 위해 dtype을 변경해야한다고 생각했습니다.
Andy Hayden

np.nan문자열로 변환되는 것을 피하기 위해 Django로 삽입하기 전에 사용하는 것이 유용 합니다"nan"
shadi

유용한 경고. 이미 만 열을 통해 루프 의미가 dtypeobject그 위해 그것을 할 필요에 따라 다르게 다른 종류의 처리. 이상적으로 fillna(None)는 훌륭 할 것입니다.
Vishal

83
df = df.replace({np.nan: None})

이 Github 문제 에 대한 크레딧은이 사람에게갑니다 .


3
이것은 df.replace({np.nan: None})임시 객체로 사용할 수있는 최상의 답변입니다
Matt

17

당신은 대체 할 수 nan와 함께 None당신의 NumPy와 배열 :

>>> x = np.array([1, np.nan, 3])
>>> y = np.where(np.isnan(x), None, x)
>>> print y
[1.0 None 3.0]
>>> print type(y[1])
<type 'NoneType'>

2
유일한 잠재적 인 우려의 변화 dtype, x.dtypedtype('float64')반면, y.dtype이다 dtype('object').
제이미

10

뒤틀린 후 이것은 나를 위해 일했습니다.

df = df.astype(object).where(pd.notnull(df),None)

4

@Andy Hayden의 답변에 추가 :

DataFrame.mask는의 반대 쌍둥이 이므로 DataFrame.where정확히 동일한 서명을 갖지만 의미는 반대입니다.

  • DataFrame.where조건이 False 인 값 바꾸기에 유용합니다 .
  • DataFrame.mask조건이 True 인 값 바꾸기에 사용됩니다 .

따라서이 질문에서 사용하는 df.mask(df.isna(), other=None, inplace=True)것이 더 직관적 일 수 있습니다.


2

또 다른 추가 : 배수를 바꾸고 열 유형을 object 에서 float로 다시 변환 할 때주의하십시오 . 당신이 당신의 것이 를 사용하여 @ andy-hayden의 제안을 적용하는 것으로 None돌아 가지 않을 것이라는 것을 확신하고 싶다면 . 교체가 여전히 '잘못'될 수있는 방법에 대한 그림 :np.NaNpd.where

In [1]: import pandas as pd

In [2]: import numpy as np

In [3]: df = pd.DataFrame({"a": [1, np.NAN, np.inf]})

In [4]: df
Out[4]:
     a
0  1.0
1  NaN
2  inf

In [5]: df.replace({np.NAN: None})
Out[5]:
      a
0     1
1  None
2   inf

In [6]: df.replace({np.NAN: None, np.inf: None})
Out[6]:
     a
0  1.0
1  NaN
2  NaN

In [7]: df.where((pd.notnull(df)), None).replace({np.inf: None})
Out[7]:
     a
0  1.0
1  NaN
2  NaN

추가해 주셔서 감사합니다. 문서를 다시 살펴보면 여전히이 동작을 이해할 수 없습니다. 어쨌든,이 아직 체인에 의해 다른 해결할 수 있습니다.replace({np.nan: None})
EliadL

1
예, 다른 replace({np.nan: None}). 내 의견은의 교체시 잠재적 인 함정을 지적하기 위해 추가되었습니다 np.nan. 위의 내용은 확실히 나를 약간 넘어 뜨 렸습니다!
gaatjeniksaan

1

꽤 오래되었지만 나는 똑같은 문제를 발견했습니다. 다음을 시도하십시오.

df['col_replaced'] = df['col_with_npnans'].apply(lambda x: None if np.isnan(x) else x)

열 데이터 유형이 숫자 인 경우 작동하지 않습니다. None은 nan으로 다시 변환되기 때문입니다 (pandas 0.23)
shadi
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.