DataFrame의 문자열이지만 dtype은 객체입니다.


96

왜 Pandas는 내가 객체를 가지고 있다고 말하는데, 선택된 열의 모든 항목은 명시 적 변환 후에도 문자열입니다.

이것은 내 DataFrame입니다.

<class 'pandas.core.frame.DataFrame'>
Int64Index: 56992 entries, 0 to 56991
Data columns (total 7 columns):
id            56992  non-null values
attr1         56992  non-null values
attr2         56992  non-null values
attr3         56992  non-null values
attr4         56992  non-null values
attr5         56992  non-null values
attr6         56992  non-null values
dtypes: int64(2), object(5)

그중 5 개는 dtype object. 이러한 객체를 문자열로 명시 적으로 변환합니다.

for c in df.columns:
    if df[c].dtype == object:
        print "convert ", df[c].name, " to string"
        df[c] = df[c].astype(str)

그런 다음, df["attr2"]여전히 가지고 dtype object있지만, type(df["attr2"].ix[0]계시 str올바른이다.

사이 팬더 구별하는 int64float64object. 그것이 없을 때 그 뒤에있는 논리는 무엇입니까 dtype str? 에 str적용되는 이유는 무엇 object입니까?


모든 "is"문자열에도 불구하고 '객체 유형'으로 인해 조인이 실패하기 때문에 여기에 왔습니다
Monica Heddneck

답변:


145

dtype 객체는 NumPy에서 제공되며 ndarray의 요소 유형을 설명합니다. ndarray의 모든 요소는 바이트 크기가 같아야합니다. int64 및 float64의 경우 8 바이트입니다. 그러나 문자열의 경우 문자열의 길이가 고정되지 않습니다. 따라서 ndarray에서 문자열의 바이트를 직접 저장하는 대신 Pandas는 객체에 대한 포인터를 저장하는 객체 ndarray를 사용합니다.이 때문에 이런 종류의 ndarray는 객체입니다.

다음은 예입니다.

  • int64 배열에는 4 개의 int64 값이 있습니다.
  • 객체 배열은 3 개의 문자열 객체에 대한 4 개의 포인터를 포함합니다.

여기에 이미지 설명 입력


3
그러나 '객체'유형 열이있는 것보다 DataFrame 읽기 / 쓰기 작업의 성능에 큰 영향을 미칩니다
erwanp

어떻게 든 문자열로 반환되는 데이터 유형을 얻을 수 있습니까? 나는 항상 type (df [ "column"]. iloc [0])을 사용할 수 있다는 것을 알고 있지만 그렇게 될 수도 있습니다. nan
user1953366

7

받아 들여지는 대답은 좋습니다. 문서참조한 답변을 제공하고 싶었습니다 . 문서는 다음과 같이 말합니다.

Pandas는 문자열을 저장하기 위해 객체 dtype을 사용합니다.

주요 코멘트에서 "걱정하지 마세요. 이렇게해야합니다." (수용된 답변은 "이유"를 설명하는 훌륭한 작업을 수행했지만 문자열은 가변 길이 임)

그러나 문자열의 경우 문자열의 길이가 고정되지 않습니다.


전달하는 모든 열을 scipy 또는 sklearn astype (str)으로 변환해야하는 이유는 무엇입니까? 처음에는 모든 열에 적용 할 수있을 것 같습니다.
Tinkinc

이해가 안 돼요 @Tinkinc 열을 문자열로 변환 하지 않으면 어떻게됩니까 ? 그리고이 대답 은 모든 열을 변환하는 우아한 방법으로 보입니다.astype(str) 여전히 문자열 변환이 필요한지 궁금 하겠지만
The Red Pea

나는 캔트 fillna (0) 대신 (1,0)의 내 dataframe 체류 (1, 유모)의 모든 객체
Tinkinc

죄송합니다 @Tinkinc 아직 이해가 안 돼요; 도와 드리고 싶지만 귀하의 문제는 Stack Overflow 댓글보다 더 복잡하게 들립니다. 질문을하거나 채팅에 참여해보세요. (당신을 초대)
레드 완두콩

5

@HYRY의 대답은 훌륭합니다. 좀 더 컨텍스트를 제공하고 싶습니다 ..

어레이로 데이터를 저장 연속 , 고정 된 크기의 메모리 블록. 이러한 속성의 조합은 데이터 액세스를 위해 어레이를 번개처럼 빠르게 만듭니다. 예를 들어, 컴퓨터가 32 비트 정수 배열 [3,0,1].

여기에 이미지 설명 입력

컴퓨터에 배열의 세 번째 요소를 가져 오도록 요청하면 처음부터 시작하여 64 비트를 건너 뛰어 세 번째 요소에 도달합니다. 건너 뛸 비트 수를 정확히 아는 것이 배열을 빠르게 만듭니다 .

이제 문자열의 순서를 고려하십시오 ['hello', 'i', 'am', 'a', 'banana']. 문자열은 크기가 다른 객체이므로 인접한 메모리 블록에 저장하려고하면 다음과 같이 보일 것입니다.

여기에 이미지 설명 입력

이제 컴퓨터는 임의로 요청 된 요소에 빠르게 액세스 할 수 없습니다. 이를 극복하기위한 열쇠는 포인터를 사용하는 것입니다. 기본적으로 각 문자열을 임의의 메모리 위치에 저장하고 각 문자열의 메모리 주소로 배열을 채 웁니다. (메모리 주소는 정수일뿐입니다.) 이제 다음과 같이 보입니다.

여기에 이미지 설명 입력

이제 컴퓨터에 이전과 마찬가지로 세 번째 요소를 가져 오도록 요청하면 64 비트 (메모리 주소가 32 비트 정수라고 가정)를 건너 뛸 수 있으며 문자열을 가져 오기위한 추가 단계를 수행 할 수 있습니다.

NumPy의 문제는 포인터가 실제로 문자열을 가리키고 있다는 보장이 없다는 것입니다. 이것이 dtype을 'object'로보고하는 이유입니다.

내가 처음에 이것을 논의했던 내 블로그 기사를 뻔뻔하게 막을 것이다.


멋지게
.. 감사합니다

1

버전 1.0.0 (2020 년 1 월)부터 pandas는 .NET을 통해 문자열 유형에 대한 최고 수준의 지원을 제공하는 실험적 기능으로 도입되었습니다 pandas.StringDtype.

object기본적으로 계속 표시되지만 dtypeof pd.StringDtype또는 간단히 'string'다음 을 지정하여 새 유형을 사용할 수 있습니다 .

>>> pd.Series(['abc', None, 'def'])
0     abc
1    None
2     def
dtype: object
>>> pd.Series(['abc', None, 'def'], dtype=pd.StringDtype())
0     abc
1    <NA>
2     def
dtype: string
>>> pd.Series(['abc', None, 'def']).astype('string')
0     abc
1    <NA>
2     def
dtype: string

2
아직 사용하지 마세요 .... 그들이 말했듯이, The implementation may change without warning.이는 새로운 업데이트가 이전 프로그램을 손상시킬 것임을 의미합니다.
NoName

1
글쎄, 그것은 모두 당신이 그것을 사용할 대상에 달려 있습니다. 지속적인 패키지 업그레이드가 필요한 프로덕션 시스템에서 사용하고 API 손상으로 인해 허용 할 수없는 유지 관리 부담이 발생하는 경우 "실험적"이라는 단어에 세심한주의를 기울이십시오.하지만 pandas를 사용하여 탐색을 수행하는 경우 작업 시간이 늘어나지 않는 스크립트에서 분석을 수행하는 경우 이러한 문제는 거의 의미가 없습니다.
fuglede

Pandas 1.1에서 API는 안정화 된 것 같습니다 . 이제 모든 dtype을 StringDtype으로 변환 할 수 있습니다 .
D3f0
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.