[python] Pandas에서 열을 문자열로 변환
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}
답변
문자열로 변환하는 한 가지 방법은 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"}'
참고 : 버퍼 / 파일을 전달하여 다른 옵션과 함께 저장할 수 있습니다 …
답변
모든 열을 문자열로 변환해야하는 경우 간단히 다음을 사용할 수 있습니다.
df = df.astype(str)
이것은 몇 개의 열을 제외한 모든 것이 문자열 / 객체가되어야하고 다른 열을 필요로하는 것으로 변환 할 때 유용합니다 (이 경우 정수).
df[["D", "E"]] = df[["D", "E"]].astype(int)
답변
다른 하나 는 여러 열을 단일 열 대신 문자열로 변환하는 데 특히 유용합니다 .
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
답변
사용 .astype (STR)
전의:
d를 Pandas DataFrame으로하자
d['Column_name'].astype(str)
답변
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
문서에서 인용 한 이유는 다음과 같습니다.
실수로 문자열과 문자열이 아닌 문자열을 오브젝트 dtype 배열에 저장할 수 있습니다. 전용 dtype을 사용하는 것이 좋습니다.
object
dtype은과 같은 dtype 특정 작업을 중단DataFrame.select_dtypes()
합니다. 텍스트가 아닌 객체 유형 열을 제외하고 텍스트 만 선택할 수있는 명확한 방법은 없습니다.코드를 읽을 때
object
dtype 배열 의 내용 이보다 명확하지 않습니다'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"
는 객체와 달리 열의 메모리 사용을 크게 줄이고 성능을 향상시키기 위해 향후 개선 사항을 기대 합니다. 그러나 그렇게 말하면 좋은 습관을들이는 것은 결코 빠르지 않습니다!
답변
이 경우 변환 기능 .apply()
과 함께 사용하면 lambda
작동합니다.
total_rows['ColumnID'] = total_rows['ColumnID'].apply(lambda x: str(x))
전체 데이터 프레임에 사용할 수 있습니다 .applymap()
. (그러나 어쨌든 .astype()
더 빠를 것 입니다)