Sorulan soru başlığı geneldir, ancak yazarlar sorunun gövdesinde belirtilen kullanım durumu özeldir. Bu nedenle başka herhangi bir cevap kullanılabilir.
Ancak başlık sorusuna tam olarak cevap verebilmek için, tüm yaklaşımların bazı durumlarda başarısız olabileceği ve biraz yeniden çalışma gerektirebileceği açıklığa kavuşturulmalıdır . Güvenilirlik sırasını düşürmek için hepsini (ve bazı eklerini) gözden geçirdim (bence):
1. Türleri doğrudan ==
(kabul edilen yanıt) aracılığıyla karşılaştırma .
Bunun kabul edilmiş bir cevap olmasına ve çoğu olumlu oyu dikkate almasına rağmen, bu yöntemin hiç kullanılmaması gerektiğini düşünüyorum. Çünkü aslında bu yaklaşım olduğunu cesaretini defalarca belirtildiği gibi Python burada .
Biri hala kullanmak istiyorsanız - gibi bazı pandalar özgü dtypes farkında olmalı pd.CategoricalDType
, pd.PeriodDtype
ya da pd.IntervalDtype
. Burada type( )
dtype'ı doğru tanımak için ekstra kullanmak gerekir :
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
Buradaki bir başka uyarı, bu tipin tam olarak belirtilmesi gerektiğidir:
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()
yaklaşım.
Şu ana kadar cevaplarda bu yöntemden bahsedilmemiştir.
Dolayısıyla, türlerin doğrudan karşılaştırılması iyi bir fikir değilse - bu amaç için yerleşik python işlevini deneyelim, yani - isinstance()
.
Başlangıçta başarısız olur, çünkü bazı nesnelerimiz olduğunu varsayar, ancak önceden tanımlanmış ancak içinde hiç nesne olmayan boş kaplar olarak kullanılabilir pd.Series
veya pd.DataFrame
kullanılabilir dtype
:
s = pd.Series([], dtype=bool)
s
>>> Series([], dtype: bool)
Ancak biri bir şekilde bu sorunun üstesinden gelirse ve her nesneye örneğin ilk satırda erişmek isterse ve dtype benzer şekilde kontrol ederse:
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')
Tek sütunda karışık veri türü olması durumunda yanıltıcı olacaktır:
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')
Ve son fakat en az değil - bu yöntem Category
dtype'ı doğrudan tanıyamaz . Dokümanlarda belirtildiği gibi :
Kategorik verilerden tek bir öğe döndürmek, "1" uzunluğunun kategorikini değil, değeri de döndürecektir.
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')
Yani bu yöntem de neredeyse uygulanamaz.
3. df.dtype.kind
yaklaşım.
Bu yöntem henüz boş çalışabilir pd.Series
veya pd.DataFrames
ancak başka sorunları olabilir.
Birincisi - bazı tipleri ayırt edemez:
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
İkincisi, benim için hala belirsiz olan şey, hatta bazı dtype'lerde geri dönüyor Hiçbiri .
4. df.select_dtypes
yaklaşım.
Bu neredeyse istediğimiz şey. Bu yöntem, pandaların içinde tasarlandı, böylece daha önce bahsedilen köşe durumlarının çoğunu idare eder - boş DataFrame'ler, uyuşuk veya pandalara özgü dtiplerden farklıdır. Tek dtype benzeri ile iyi çalışır .select_dtypes('bool')
. Dtype'a göre sütun gruplarını seçmek için bile kullanılabilir:
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')
Tıpkı belgelerde belirtildiği gibi :
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
On, burada ilk beklenmedik (eskiden benim için: soru ) sonuçları gördüğümüzü düşünebilir - TimeDelta
çıktıya dahil edilir DataFrame
. Ama tersine yanıtlandığı gibi , öyle olmalı, ancak kişi bunun farkında olmalı. Not o bool
da birisi için istenmeyen olabileceğini, atlanır d_type, ancak nedeniyle olduğunu bool
ve number
farklı "olan alt ağaçlar numpy dtypes arasında". Bool durumunda, test.select_dtypes(['bool'])
burada kullanabiliriz .
Bu yöntemin bir sonraki kısıtlayıcı pandalarıyla mevcut versiyonu (0.24.2) için, bu kod olmasıdır test.select_dtypes('period')
yükseltecektir NotImplementedError
.
Ve başka bir şey de dizeleri diğer nesnelerden ayırt edememesidir:
test.select_dtypes('object')
>>> str obj
>>> 0 s1 [1, 2, 3]
>>> 1 s2 [5435, 35, -52, 14]
Ancak bu, ilk olarak - daha önce belgelerde bahsedilmiştir . Ve ikincisi - bu yöntemin sorunu değil, dizelerin depolanma şeklidir DataFrame
. Ama yine de bu davada bazı sonradan işlemlerin yapılması gerekiyor.
5. df.api.types.is_XXX_dtype
yaklaşım.
Bunun, tahmin ettiğim gibi, dtype tanıma (işlevlerin bulunduğu modülün yolu kendi kendine söyler) elde etmenin en sağlam ve doğal yolu olması amaçlanmıştır. Ve neredeyse mükemmel çalışıyor, ancak yine de en az bir uyarısı var ve yine de bir şekilde dize sütunlarını ayırt etmesi gerekiyor .
Ayrıca, bu öznel olabilir, ancak bu yaklaşım aynı zamanda aşağıdakilere number
kıyasla daha 'insan tarafından anlaşılabilir' dtype grup işlemesine sahiptir .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
Hayır timedelta
ve bool
dahildir. Mükemmel.
Ardışık düzenim, şu anda tam olarak bu işlevsellikten ve ayrıca bir miktar el sonrası işlemden yararlanıyor.
Çıktı.
Umarım ana noktayı tartışabilmişimdir - tartışılan tüm yaklaşımlar kullanılabilir, ancak sadece pd.DataFrame.select_dtypes()
ve pd.api.types.is_XXX_dtype
gerçekten uygulanabilir olanlar olarak düşünülmelidir.
string
bir dtype değil