質問のタイトルは一般的ですが、質問の本文に記載されている著者の使用例は特定のものです。したがって、他の回答を使用することができます。
ただし、タイトルの質問に完全に回答するには、すべてのアプローチが失敗する可能性があり、再作業が必要になる場合があることを明確にしておく必要があります。(私の意見では)信頼性の順序を下げる際にそれらすべて(およびいくつかの追加)を確認しました。
1. ==
(受け入れられた回答)を介してタイプを直接比較する。
これは受け入れられた回答であり、賛成票が最も多いという事実にもかかわらず、この方法はまったく使用すべきではないと思います。実際、このアプローチは、ここで何度か言及されているように、Pythonでは推奨されていません。
1はまだそれを使用したい場合でも、 -のようないくつかのパンダ特有のdtypesに注意する必要がありますpd.CategoricalDType
、pd.PeriodDtype
またはpd.IntervalDtype
。ここでは、type( )
dtypeを正しく認識するために、extraを使用する必要があります。
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
ここでのもう1つの注意点は、型を正確に指摘する必要があることです。
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()
アプローチ。
この方法は、これまでの回答では言及されていません。
したがって、型を直接比較することが適切でない場合は、この目的のために組み込みのPython関数を試してみましょう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')
そして最後にCategory
重要なことですが、このメソッドはdtypeを直接認識できません。ドキュメントで述べたように:
カテゴリデータから単一のアイテムを返すと、長さ「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
アプローチ。
これはほとんど私たちが望んでいることです。このメソッドはパンダの内部で設計されているため、前述のほとんどのコーナーケースを処理します。空のデータフレームは、numpyまたはpandas固有のdtypeとは異なります。のような単一の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はスキップされ、それはまた、誰かのために望ましくないことがありますが、それはのためにだbool
とnumber
違う「にあるサブツリー numpyのdtypesの」。boolの場合、test.select_dtypes(['bool'])
こちらを使用することがあります。
このメソッドの次の制限は、現在のバージョンのパンダ(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]
しかし、これは最初です-すでにドキュメントで言及されています。そして2番目-このメソッドの問題ではなく、文字列の格納方法DataFrame
です。しかし、とにかく、このケースにはいくつかの後処理が必要です。
5. df.api.types.is_XXX_dtype
アプローチ。
これは、私が想定しているように、dtype認識(関数が存在するモジュールのパスはそれ自体で言う)を実現するための最も堅牢でネイティブな方法であることを意図しています。そして、それはほぼ完璧に機能しますが、それでも少なくとも1つの注意点があり、文字列の列を何らかの方法で区別する必要があります。
その上、これは主観的である可能性がありますが、このアプローチには、より「人間が理解できる」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
含まれています。完璧です。
私のパイプラインは、現時点でまさにこの機能を利用しており、少し後処理も行っています。
出力。
すべての議論のアプローチを使用することができるが、唯一のこと-希望私は、引数に要点ができましたpd.DataFrame.select_dtypes()
し、pd.api.types.is_XXX_dtype
実際に適用されるものと考えるべきです。
string
はdtypeではありません