python pandas에서 열의 dtype을 확인하는 방법


133

숫자 열과 문자열 열을 처리하려면 다른 함수를 사용해야합니다. 내가 지금하고있는 일은 정말 멍청하다.

allc = list((agg.loc[:, (agg.dtypes==np.float64)|(agg.dtypes==np.int)]).columns)
for y in allc:
    treat_numeric(agg[y])    

allc = list((agg.loc[:, (agg.dtypes!=np.float64)&(agg.dtypes!=np.int)]).columns)
for y in allc:
    treat_str(agg[y])    

이 작업을 수행하는 더 우아한 방법이 있습니까? 예

for y in agg.columns:
    if(dtype(agg[y]) == 'string'):
          treat_str(agg[y])
    elif(dtype(agg[y]) != 'string'):
          treat_numeric(agg[y])

2
stringDTYPE 아니다
데이비드 로빈슨

답변:


124

다음을 사용하여 열의 데이터 유형에 액세스 할 수 있습니다 dtype.

for y in agg.columns:
    if(agg[y].dtype == np.float64 or agg[y].dtype == np.int64):
          treat_numeric(agg[y])
    else:
          treat_str(agg[y])

1
안녕하세요 David, == np.float64를 포함시킨 이유에 대해 설명해 주시겠습니까? 우리는 수레로 변환하려고하지 않습니까? 감사.
Ryan Chase

@RyanChase이 질문의 OP는 그가 float로 변환한다고 말한 적이 없으며, (지정되지 않은) treat_numeric함수 를 사용할지 여부를 알아야만했습니다 . 그는 agg.dtypes==np.float64옵션으로 포함했기 때문에 나도했다.
David Robinson

3
numpy에는이 두 가지보다 더 많은 숫자 유형이 number있습니다. 모든 것은 여기 아래에 있습니다. docs.scipy.org/doc/numpy-1.13.0/reference/arrays.scalars.html 일반적인 해결책은is_numeric_dtype(agg[y])
Attila Tanyi 2017 년

96

에서 pandas 0.20.2당신이 할 수 있습니다 :

from pandas.api.types import is_string_dtype
from pandas.api.types import is_numeric_dtype

is_string_dtype(df['A'])
>>>> True

is_numeric_dtype(df['B'])
>>>> True

따라서 코드는 다음과 같습니다.

for y in agg.columns:
    if (is_string_dtype(agg[y])):
        treat_str(agg[y])
    elif (is_numeric_dtype(agg[y])):
        treat_numeric(agg[y])

1
이전 판다 버전에 대한 대안이 있습니까? 오류가 발생합니다. api.types라는 모듈이 없습니다.
rph

2
pandas.core.common.is_numeric_dtypePandas 0.13 이후로 존재했으며 동일한 작업을 수행하지만 pandas.api.types.is_numeric_dtype0.19에서 더 이상 사용되지 않습니다 . 제 생각에는
Migwell

대부분의 원어민 답변입니다. 그러나 여기서 몇 가지 주의 사항을 알고 있어야 합니다.
BeforeFlight 19

46

나는 이것이 약간 오래된 스레드라는 것을 알고 있지만 pandas 19.02를 사용하면 다음을 수행 할 수 있습니다.

df.select_dtypes(include=['float64']).apply(your_function)
df.select_dtypes(exclude=['string','object']).apply(your_other_function)

http://pandas.pydata.org/pandas-docs/version/0.19.2/generated/pandas.DataFrame.select_dtypes.html


1
좋은 대답은 아마도 include[np.number]첫 번째 줄과 exclude[object]두 번째 줄에 대해 ( int 및 32 비트 부동 소수점도 포함하기 위해) 할 것입니다 . 문자열은 dtype에 관한 한 객체입니다. 사실 '문자열'을 객체에 포함하면 오류가 발생합니다.
JohnE

1
"문자열"이 더 이상 지원되지 않는 것 같습니다. 대신 "개체"를 사용해야합니다. 그러나 확실히 정답 :)
Bertrand

또한 'period'dtype이 NotImplementedError현재 발생 하고 있음을 주목해야합니다 (pandas 0.24.2). 그래서 하나는 수제 후 처리가 필요할 수 있습니다.
BeforeFlight

21

질문 제목은 일반적이지만 질문 본문에 명시된 작성자 사용 사례는 구체적입니다. 따라서 다른 답변을 사용할 수 있습니다.

그러나 제목 질문 에 완전히 답하려면 모든 접근 방식이 어떤 경우에는 실패 하고 약간의 재 작업이 필요할 수 있다는 점을 명확히해야합니다 . 나는 신뢰성 순서를 낮추면서 (내 의견으로는) 그들 모두 (및 일부 추가)를 검토했습니다.

1. ==(허용 된 답변)을 통해 직접 유형 비교 .

이것이 허용되는 답변이고 대부분의 찬성표가 있다는 사실에도 불구 하고이 방법은 전혀 사용해서는 안됩니다. 사실이 접근 방식은 여기에서 여러 번 언급했듯이 파이썬에서는 권장되지 않습니다 . 하나는 여전히 그것을 사용하고자한다면 - 같은 몇 가지 팬더 고유의 dtypes 알고 있어야합니다 , 또는 . dtype을 올바르게 인식 하려면 extra를 사용해야 합니다.
pd.CategoricalDTypepd.PeriodDtypepd.IntervalDtypetype( )

s = pd.Series([pd.Period('2002-03','D'), pd.Period('2012-02-01', 'D')])
s
s.dtype == pd.PeriodDtype   # Not working
type(s.dtype) == pd.PeriodDtype # working 

>>> 0    2002-03-01
>>> 1    2012-02-01
>>> dtype: period[D]
>>> False
>>> True

여기서 또 다른주의 사항은 유형을 정확하게 지적해야한다는 것입니다.

s = pd.Series([1,2])
s
s.dtype == np.int64 # Working
s.dtype == np.int32 # Not working

>>> 0    1
>>> 1    2
>>> dtype: int64
>>> True
>>> False

2. isinstance()접근.

이 방법은 지금까지 답변에서 언급되지 않았습니다.

따라서 유형을 직접 비교하는 것이 좋은 생각이 아니라면이 목적을 위해 내장 된 파이썬 함수, 즉- isinstance().
우리가 어떤 객체를 가지고 있지만 가정하기 때문에 그것은 단지 시작에 실패 pd.Series또는 pd.DataFrame단지 빈 미리 정의와 용기로 사용할 수 dtype있지만, 거기에 물체를 :

s = pd.Series([], dtype=bool)
s

>>> Series([], dtype: bool)

그러나 어떤 식 으로든이 문제를 극복하고 예를 들어 첫 번째 행에서 각 개체에 액세스하고 dtype을 다음과 같이 확인하려는 경우 :

df = pd.DataFrame({'int': [12, 2], 'dt': [pd.Timestamp('2013-01-02'), pd.Timestamp('2016-10-20')]},
                  index = ['A', 'B'])
for col in df.columns:
    df[col].dtype, 'is_int64 = %s' % isinstance(df.loc['A', col], np.int64)

>>> (dtype('int64'), 'is_int64 = True')
>>> (dtype('<M8[ns]'), 'is_int64 = False')

단일 열에 혼합 된 데이터 유형의 경우 오해의 소지가 있습니다.

df2 = pd.DataFrame({'data': [12, pd.Timestamp('2013-01-02')]},
                  index = ['A', 'B'])
for col in df2.columns:
    df2[col].dtype, 'is_int64 = %s' % isinstance(df2.loc['A', col], np.int64)

>>> (dtype('O'), 'is_int64 = False')

마지막으로이 방법은 Categorydtype을 직접 인식 할 수 없습니다 . 문서에 명시된 바와 같이 :

범주 형 데이터에서 단일 항목을 반환하면 길이가 "1"인 범주 형이 아닌 값도 반환됩니다.

df['int'] = df['int'].astype('category')
for col in df.columns:
    df[col].dtype, 'is_int64 = %s' % isinstance(df.loc['A', col], np.int64)

>>> (CategoricalDtype(categories=[2, 12], ordered=False), 'is_int64 = True')
>>> (dtype('<M8[ns]'), 'is_int64 = False')

따라서이 방법도 거의 적용 할 수 없습니다.

3. df.dtype.kind접근.

이 방법은 아직 비어 pd.Series있거나 pd.DataFrames다른 문제가 있을 수 있습니다.

첫째-일부 dtype을 다를 수 없습니다.

df = pd.DataFrame({'prd'  :[pd.Period('2002-03','D'), pd.Period('2012-02-01', 'D')],
                   'str'  :['s1', 's2'],
                   'cat'  :[1, -1]})
df['cat'] = df['cat'].astype('category')
for col in df:
    # kind will define all columns as 'Object'
    print (df[col].dtype, df[col].dtype.kind)

>>> period[D] O
>>> object O
>>> category O

둘째, 실제로 아직 명확하지 않은 것은 일부 dtypes None 에서도 반환됩니다 .

4. df.select_dtypes접근.

이것이 우리가 원하는 것입니다. 이 메서드는 pandas 내부에서 설계되어 이전에 언급 된 대부분의 코너 케이스 (빈 DataFrames, numpy 또는 pandas 특정 dtypes와 잘 다릅니다)를 처리합니다. 같은 단일 dtype에서 잘 작동합니다 .select_dtypes('bool'). dtype을 기반으로 열 그룹을 선택하는 데에도 사용할 수 있습니다.

test = pd.DataFrame({'bool' :[False, True], 'int64':[-1,2], 'int32':[-1,2],'float': [-2.5, 3.4],
                     'compl':np.array([1-1j, 5]),
                     'dt'   :[pd.Timestamp('2013-01-02'), pd.Timestamp('2016-10-20')],
                     'td'   :[pd.Timestamp('2012-03-02')- pd.Timestamp('2016-10-20'),
                              pd.Timestamp('2010-07-12')- pd.Timestamp('2000-11-10')],
                     'prd'  :[pd.Period('2002-03','D'), pd.Period('2012-02-01', 'D')],
                     'intrv':pd.arrays.IntervalArray([pd.Interval(0, 0.1), pd.Interval(1, 5)]),
                     'str'  :['s1', 's2'],
                     'cat'  :[1, -1],
                     'obj'  :[[1,2,3], [5435,35,-52,14]]
                    })
test['int32'] = test['int32'].astype(np.int32)
test['cat'] = test['cat'].astype('category')

마찬가지로 문서에 명시된 바와 같이 :

test.select_dtypes('number')

>>>     int64   int32   float   compl   td
>>> 0      -1      -1   -2.5    (1-1j)  -1693 days
>>> 1       2       2    3.4    (5+0j)   3531 days

여기에서 예상치 못한 첫 번째 (예전에는 질문 ) 결과 TimeDelta가 출력에 포함 되었다고 생각할 수 있습니다 DataFrame. 그러나 반대로 대답 했듯이 그것은 그렇게되어야하지만 우리는 그것을 알아야합니다. 참고 것을 bool또한 누군가를 위해 바람직하지 않은 될 수있는, 생략 DTYPE이되지만 때문입니다 boolnumber다른 "에있는 서브 트리 NumPy와 dtypes의". bool의 경우 test.select_dtypes(['bool'])여기에서 사용할 수 있습니다.

이 메서드의 다음 제한 사항은 현재 버전의 pandas (0.24.2)에 대해 다음 코드 test.select_dtypes('period')NotImplementedError.

그리고 또 다른 것은 다른 객체와 문자열을 구별 할 수 없다는 것입니다.

test.select_dtypes('object')

>>>     str     obj
>>> 0    s1     [1, 2, 3]
>>> 1    s2     [5435, 35, -52, 14]

그러나 이것은 먼저 문서에서 이미 언급 되었습니다. 두 번째는이 방법의 문제가 아니라 문자열이 DataFrame. 그러나 어쨌든이 경우에는 약간의 후 처리가 필요합니다.

5. df.api.types.is_XXX_dtype접근.

이것은 내가 생각하는 것처럼 dtype 인식 (함수가 상주하는 모듈의 경로가 자체적으로 말합니다)을 달성하는 가장 강력하고 기본 방법입니다. 그리고 거의 완벽하게 작동하지만 여전히 최소한 한 가지주의 사항이 있으며 여전히 문자열 열을 구분해야합니다 .

게다가 이것은 주관적 일 수 있지만이 접근 방식은 다음 number과 비교하여 더 '인간이 이해할 수있는' dtypes 그룹 처리를 제공합니다 .select_dtypes('number').

for col in test.columns:
    if pd.api.types.is_numeric_dtype(test[col]):
        print (test[col].dtype)

>>> bool
>>> int64
>>> int32
>>> float64
>>> complex128

아니요 timedelta, bool포함됩니다. 완전한.

내 파이프 라인은이 순간에 정확히이 기능과 약간의 사후 처리를 활용합니다.

산출.

모든 논의 방식이 사용될 수 있지만 있음 - 희망 I는 인수의 주요 지점 수 있었다 pd.DataFrame.select_dtypes()그리고 pd.api.types.is_XXX_dtype실제로 적용 할 수있는 사람으로 간주되어야한다.


1
훌륭하고 잘 구성된 대답. :-)
Oliver

8

데이터 프레임 열의 유형을 문자열로 표시하려면 다음을 수행 할 수 있습니다.

df['A'].dtype.kind

예 :

In [8]: df = pd.DataFrame([[1,'a',1.2],[2,'b',2.3]])
In [9]: df[0].dtype.kind, df[1].dtype.kind, df[2].dtype.kind
Out[9]: ('i', 'O', 'f')

코드에 대한 답 :

for y in agg.columns:
    if(agg[y].dtype.kind == 'f' or agg[y].dtype.kind == 'i'):
          treat_numeric(agg[y])
    else:
          treat_str(agg[y])

4

열 데이터 유형을 예쁘게 인쇄하려면

예를 들어 파일에서 가져온 후 데이터 유형을 확인하려면

def printColumnInfo(df):
    template="%-8s %-30s %s"
    print(template % ("Type", "Column Name", "Example Value"))
    print("-"*53)
    for c in df.columns:
        print(template % (df[c].dtype, c, df[c].iloc[1]) )

예시 출력 :

Type     Column Name                    Example Value
-----------------------------------------------------
int64    Age                            49
object   Attrition                      No
object   BusinessTravel                 Travel_Frequently
float64  DailyRate                      279.0
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.