Pandas에서 열을 문자열로 변환


179

SQL 쿼리에서 다음 DataFrame이 있습니다.

(Pdb) pp total_rows
     ColumnID  RespondentCount
0          -1                2
1  3030096843                1
2  3030096845                1

나는 이것을 다음과 같이 피벗하고 싶다 :

total_data = total_rows.pivot_table(cols=['ColumnID'])

(Pdb) pp total_data
ColumnID         -1            3030096843   3030096845
RespondentCount            2            1            1

[1 rows x 3 columns]


total_rows.pivot_table(cols=['ColumnID']).to_dict('records')[0]

{3030096843: 1, 3030096845: 1, -1: 2}

하지만 303 열을 정수 대신 문자열로 캐스팅하여 이것을 얻을 수 있도록하고 싶습니다.

{'3030096843': 1, '3030096845': 1, -1: 2}

pandas 1.0부터 문서astype("string")astype(str) 는 몇 가지 좋은 이유로 대신 사용 하는 것이 좋습니다 .
cs95

답변:


332

문자열로 변환하는 한 가지 방법은 astype 을 사용하는 것입니다 .

total_rows['ColumnID'] = total_rows['ColumnID'].astype(str)

그러나 아마도 to_json키를 유효한 json (따라서 키를 문자열로)로 변환 하는 함수를 찾고 있을 것입니다.

In [11]: df = pd.DataFrame([['A', 2], ['A', 4], ['B', 6]])

In [12]: df.to_json()
Out[12]: '{"0":{"0":"A","1":"A","2":"B"},"1":{"0":2,"1":4,"2":6}}'

In [13]: df[0].to_json()
Out[13]: '{"0":"A","1":"A","2":"B"}'

참고 : 버퍼 / 파일을 전달하여 다른 옵션과 함께 저장할 수 있습니다 ...


3
내가) (to_string하기 때문에 NULL을 보존하는 것이 바람직하다 생각 stackoverflow.com/a/44008334/3647167
키스

1
@Keith null 보존은 매력적입니다. 그러나 의사는 그 목적이 '데이터 프레임을 콘솔 친화적 인 테이블 형식 출력으로 렌더링하는 것'이라고 말합니다. 권위있는 사람이 체중을 측정하고 싶습니다
3pitt

to_json()아마도 astype(str)datetime64와 그 서브 클래스를 획기 이후 밀리 초로 남겨두면 호출하지 않을 것입니다 .
Sussch

1
@ Susch json에는 명시적인 날짜 시간 형식이 없기 때문에 시간이 오래 걸리기 때문입니다. 즉, 그것이 표준이라고 생각합니다.
Andy Hayden

49

모든 열을 문자열로 변환해야하는 경우 간단히 다음을 사용할 수 있습니다.

df = df.astype(str)

이것은 몇 개의 열을 제외한 모든 것이 문자열 / 객체가되어야하고 다른 열을 필요로하는 것으로 변환 할 때 유용합니다 (이 경우 정수).

 df[["D", "E"]] = df[["D", "E"]].astype(int) 

28

다른 하나 는 여러 열을 단일 열 대신 문자열로 변환하는 데 특히 유용합니다 .

In [76]: import numpy as np
In [77]: import pandas as pd
In [78]: df = pd.DataFrame({
    ...:     'A': [20, 30.0, np.nan],
    ...:     'B': ["a45a", "a3", "b1"],
    ...:     'C': [10, 5, np.nan]})
    ...: 

In [79]: df.dtypes ## Current datatype
Out[79]: 
A    float64
B     object
C    float64
dtype: object

## Multiple columns string conversion
In [80]: df[["A", "C"]] = df[["A", "C"]].astype(str) 

In [81]: df.dtypes ## Updated datatype after string conversion
Out[81]: 
A    object
B    object
C    object
dtype: object


0

pandas> = 1.0 : 이제 사용을 중지 할 차례입니다 astype(str)!

pandas 1.0 (실제로는 0.25) 이전에는 Series / column을 문자열로 선언하는 사실상의 방법이었습니다.

# pandas <= 0.25
# Note to pedants: specifying the type is unnecessary since pandas will 
# automagically infer the type as object
s = pd.Series(['a', 'b', 'c'], dtype=str)
s.dtype
# dtype('O')

pandas 1.0부터 "string"type을 대신 사용하십시오.

# pandas >= 1.0
s = pd.Series(['a', 'b', 'c'], dtype="string")
s.dtype
# StringDtype

문서에서 인용 한 이유는 다음과 같습니다.

  1. 실수로 문자열과 문자열이 아닌 문자열을 오브젝트 dtype 배열에 저장할 수 있습니다. 전용 dtype을 사용하는 것이 좋습니다.

  2. objectdtype은과 같은 dtype 특정 작업을 중단 DataFrame.select_dtypes()합니다. 텍스트가 아닌 객체 유형 열을 제외하고 텍스트 만 선택할 수있는 명확한 방법은 없습니다.

  3. 코드를 읽을 때 objectdtype 배열 의 내용 이보다 명확하지 않습니다 'string'.

과의 행동 차이"string"object 에 관한 섹션도 참조하십시오 .

확장 유형 (0.24에 도입되고 1.0으로 공식화 됨)은 numpy보다 팬더에 더 가깝습니다. numpy 유형은 충분히 강력하지 않기 때문에 좋습니다. 예를 들어 NumPy에는 정수 데이터에서 누락 된 데이터를 나타내는 방법이 없습니다 (이후 type(NaN) == float). 그러나 팬더는 Nullable Integer 열을 사용할 수 있습니다 .


왜 사용을 중단해야합니까?

실수로 dtypes 혼합
문서에 설명 된 첫 번째 이유는 실수로 텍스트가 아닌 데이터를 개체 열에 저장할 수 있기 때문입니다.

# pandas <= 0.25
pd.Series(['a', 'b', 1.23])   # whoops, this should have been "1.23"

0       a
1       b
2    1.23
dtype: object

pd.Series(['a', 'b', 1.23]).tolist()
# ['a', 'b', 1.23]   # oops, pandas was storing this as float all the time.
# pandas >= 1.0
pd.Series(['a', 'b', 1.23], dtype="string")

0       a
1       b
2    1.23
dtype: string

pd.Series(['a', 'b', 1.23], dtype="string").tolist()
# ['a', 'b', '1.23']   # it's a string and we just averted some potentially nasty bugs.

문자열과 다른 파이썬 객체
를 구별하기 어려운 또 다른 명백한 예는 "문자열"과 "객체"를 구별하기가 더 어렵다는 것입니다. 객체는 기본적으로 벡터화 가능한 연산을 지원하지 않는 모든 유형의 블랭킷 유형입니다 .

치다,

# Setup
df = pd.DataFrame({'A': ['a', 'b', 'c'], 'B': [{}, [1, 2, 3], 123]})
df
 
   A          B
0  a         {}
1  b  [1, 2, 3]
2  c        123

팬더 0.25까지는 "A"와 "B"가 동일한 유형의 데이터를 가지고 있지 않다는 것을 구별 할 방법이 거의 없었습니다.

# pandas <= 0.25  
df.dtypes

A    object
B    object
dtype: object

df.select_dtypes(object)

   A          B
0  a         {}
1  b  [1, 2, 3]
2  c        123

pandas 1.0부터는 훨씬 간단 해졌습니다.

# pandas >= 1.0
# Convenience function I call to help illustrate my point.
df = df.convert_dtypes()
df.dtypes

A    string
B    object
dtype: object

df.select_dtypes("string")

   A
0  a
1  b
2  c

가독성
이것은 자명하다 ;-)


좋아, 지금 사용을 중단해야합니까?

...아니. 이 답변 (버전 1.1)을 작성할 때 성능상의 이점은 없지만 문서 "string"는 객체와 달리 열의 메모리 사용을 크게 줄이고 성능을 향상시키기 위해 향후 개선 사항을 기대 합니다. 그러나 그렇게 말하면 좋은 습관을들이는 것은 결코 빠르지 않습니다!


-1

이 경우 변환 기능 .apply()과 함께 사용하면 lambda작동합니다.

total_rows['ColumnID'] = total_rows['ColumnID'].apply(lambda x: str(x))

전체 데이터 프레임에 사용할 수 있습니다 .applymap(). (그러나 어쨌든 .astype()더 빠를 것 입니다)

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