[python] 팬더에서 공백 값 (공백)을 NaN으로 바꾸기

공백 (임의의 양)을 포함하는 Pandas 데이터 프레임에서 모든 값을 찾고 해당 값을 NaN으로 바꾸고 싶습니다.

이것이 어떻게 개선 될 수있는 아이디어가 있습니까?

기본적으로 나는 이것을 돌리고 싶다 :

                   A    B    C
2000-01-01 -0.532681  foo    0
2000-01-02  1.490752  bar    1
2000-01-03 -1.387326  foo    2
2000-01-04  0.814772  baz     
2000-01-05 -0.222552         4
2000-01-06 -1.176781  qux     

이것으로 :

                   A     B     C
2000-01-01 -0.532681   foo     0
2000-01-02  1.490752   bar     1
2000-01-03 -1.387326   foo     2
2000-01-04  0.814772   baz   NaN
2000-01-05 -0.222552   NaN     4
2000-01-06 -1.176781   qux   NaN

아래 코드를 사용하여 관리했지만 사람이 못 생겼습니다. 그것은 Pythonic이 아니며 팬더를 가장 효율적으로 사용하지 않는다고 확신합니다. 각 열을 반복하고 공백에 일치하는 각 값의 정규식 검색을 수행하는 함수를 적용하여 생성 된 열 마스크에 대해 부울 대체를 수행합니다.

for i in df.columns:
    df[i][df[i].apply(lambda i: True if re.search('^\s*$', str(i)) else False)]=None

빈 문자열을 포함 할 수있는 필드 만 반복하여 약간 최적화 할 수 있습니다.

if df[i].dtype == np.dtype('object')

하지만 그다지 개선되지는 않았습니다.

그리고 마지막으로,이 코드는 팬더 ‘기능처럼 작동 없음에 대상 문자열을 설정 fillna()하지만, 만약 내가 할 수 실제로 삽입 완전성에 대한 좋은 것 NaN대신 직접 None.



답변

팬더 0.13df.replace() 부터 일을 한다고 생각 합니다 .

df = pd.DataFrame([
    [-0.532681, 'foo', 0],
    [1.490752, 'bar', 1],
    [-1.387326, 'foo', 2],
    [0.814772, 'baz', ' '],
    [-0.222552, '   ', 4],
    [-1.176781,  'qux', '  '],
], columns='A B C'.split(), index=pd.date_range('2000-01-01','2000-01-06'))

# replace field that's entirely space (or empty) with NaN
print(df.replace(r'^\s*$', np.nan, regex=True))

생산 :

                   A    B   C
2000-01-01 -0.532681  foo   0
2000-01-02  1.490752  bar   1
2000-01-03 -1.387326  foo   2
2000-01-04  0.814772  baz NaN
2000-01-05 -0.222552  NaN   4
2000-01-06 -1.176781  qux NaN

으로 Temak이 그것을 지적 사용하는 df.replace(r'^\s+$', np.nan, regex=True)경우에 대비하여 유효한 데이터가 공백이 포함되어 있습니다.


답변

빈 문자열과 레코드를 공백으로 바꾸려면 올바른 대답은 !입니다.

df = df.replace(r'^\s*$', np.nan, regex=True)

허용 된 답변

df.replace(r'\s+', np.nan, regex=True)

빈 문자열을 대체하지 않습니다! 주어진 약간의 예제를 사용하여 시도해 볼 수 있습니다.

df = pd.DataFrame([
    [-0.532681, 'foo', 0],
    [1.490752, 'bar', 1],
    [-1.387326, 'fo o', 2],
    [0.814772, 'baz', ' '],
    [-0.222552, '   ', 4],
    [-1.176781,  'qux', ''],
], columns='A B C'.split(), index=pd.date_range('2000-01-01','2000-01-06'))

또한 ‘fo o’는 공백을 포함하지만 Nan으로 대체되지 않습니다. 더 간단한 점은 다음과 같습니다.

df.replace(r'', np.NaN)

작동하지 않습니다-사용해보십시오.


답변

어때요?

d = d.applymap(lambda x: np.nan if isinstance(x, basestring) and x.isspace() else x)

applymap함수는 함수를 데이터 프레임의 모든 셀에 적용합니다.


답변

나는 이것을 할 것이다 :

df = df.apply(lambda x: x.str.strip()).replace('', np.nan)

또는

df = df.apply(lambda x: x.str.strip() if isinstance(x, str) else x).replace('', np.nan)

모든 str을 제거한 다음 빈 str을로 바꿉니다 np.nan.


답변

가장 간단한 솔루션 :

df = df.replace(r'^\s+$', np.nan, regex=True)


답변

CSV 파일에서 데이터를 내보내는 경우 다음과 같이 간단 할 수 있습니다.

df = pd.read_csv(file_csv, na_values=' ')

이렇게하면 데이터 프레임이 생성되고 빈 값이 Na로 바뀝니다.


답변

단일 값에 대해 동등성을 검사하는 매우 빠르고 간단한 솔루션의 경우이 mask방법을 사용할 수 있습니다 .

df.mask(df == ' ')