Bagaimana cara menentukan apakah kolom / variabel numerik atau tidak di Pandas / NumPy?

90

Apakah ada cara yang lebih baik untuk menentukan apakah variabel dalam Pandasdan / atau NumPyyang numericatau tidak?

Saya memiliki definisi sendiri dictionarydengan dtypessebagai kunci dan numeric/ notsebagai nilai.

pengguna2808117
sumber
16
Anda bisa memeriksanya dtype.kind in 'biufc'.
Jaime
1
Komentar di atas yang diposting oleh Jaime, lebih sederhana dari yang di bawah ini dan sepertinya berfungsi dengan baik ...... terima kasih
hfrog713

Jawaban:

101

Dalam pandas 0.20.2Anda dapat melakukan:

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

df = pd.DataFrame({'A': ['a', 'b', 'c'], 'B': [1.0, 2.0, 3.0]})

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

is_numeric_dtype(df['B'])
>>>> True
danthelion
sumber
Saya akan mengatakan ini adalah solusi yang lebih elegan. Terima kasih
seolah - jika
85

Anda dapat menggunakan np.issubdtypeuntuk memeriksa apakah dtype adalah sub dtype dari np.number. Contoh:

np.issubdtype(arr.dtype, np.number)  # where arr is a numpy array
np.issubdtype(df['X'].dtype, np.number)  # where df['X'] is a pandas Series

Ini berfungsi untuk dtypes numpy tetapi gagal untuk tipe tertentu panda seperti pd. Kategorikal seperti yang dicatat Thomas . Jika Anda menggunakan is_numeric_dtypefungsi kategorikal dari pandas adalah alternatif yang lebih baik daripada np.issubdtype.

df = pd.DataFrame({'A': [1, 2, 3], 'B': [1.0, 2.0, 3.0], 
                   'C': [1j, 2j, 3j], 'D': ['a', 'b', 'c']})
df
Out: 
   A    B   C  D
0  1  1.0  1j  a
1  2  2.0  2j  b
2  3  3.0  3j  c

df.dtypes
Out: 
A         int64
B       float64
C    complex128
D        object
dtype: object

np.issubdtype(df['A'].dtype, np.number)
Out: True

np.issubdtype(df['B'].dtype, np.number)
Out: True

np.issubdtype(df['C'].dtype, np.number)
Out: True

np.issubdtype(df['D'].dtype, np.number)
Out: False

Untuk beberapa kolom, Anda dapat menggunakan np.vectorize:

is_number = np.vectorize(lambda x: np.issubdtype(x, np.number))
is_number(df.dtypes)
Out: array([ True,  True,  True, False], dtype=bool)

Dan untuk seleksi, panda sekarang memiliki select_dtypes:

df.select_dtypes(include=[np.number])
Out: 
   A    B   C
0  1  1.0  1j
1  2  2.0  2j
2  3  3.0  3j
ayhan
sumber
1
Ini tampaknya tidak bekerja dengan andal dengan DataFrames pandas, karena itu mungkin mengembalikan kategori yang tidak diketahui ke numpy seperti "kategori". Numpy kemudian melempar "TypeError: tipe data tidak dipahami"
Thomas
23

Berdasarkan jawaban @ jaime di kolom komentar, perlu dicek .dtype.kinddi kolom yang menarik. Sebagai contoh;

>>> import pandas as pd
>>> df = pd.DataFrame({'numeric': [1, 2, 3], 'not_numeric': ['A', 'B', 'C']})
>>> df['numeric'].dtype.kind in 'biufc'
>>> True
>>> df['not_numeric'].dtype.kind in 'biufc'
>>> False

NB Arti dari biufc: bbool, iint (signed), uunsigned int, ffloat, ccomplex. Lihat https://docs.scipy.org/doc/numpy/reference/generated/numpy.dtype.kind.html#numpy.dtype.kind

danodonovan
sumber
3
Berikut adalah daftar semua jenis dtype [1]. Huruf kecil uadalah untuk bilangan bulat tak bertanda tangan; huruf besar Uuntuk unicode. [1]: docs.scipy.org/doc/numpy/reference/generated/…
cbarrick
7

Panda memiliki select_dtypefungsi. Anda dapat dengan mudah memfilter kolom Anda di int64 , dan float64 seperti ini:

df.select_dtypes(include=['int64','float64'])
farshad madani
sumber
4

Ini adalah metode pseudo-internal untuk mengembalikan hanya data tipe numerik

In [27]: df = DataFrame(dict(A = np.arange(3), 
                             B = np.random.randn(3), 
                             C = ['foo','bar','bah'], 
                             D = Timestamp('20130101')))

In [28]: df
Out[28]: 
   A         B    C                   D
0  0 -0.667672  foo 2013-01-01 00:00:00
1  1  0.811300  bar 2013-01-01 00:00:00
2  2  2.020402  bah 2013-01-01 00:00:00

In [29]: df.dtypes
Out[29]: 
A             int64
B           float64
C            object
D    datetime64[ns]
dtype: object

In [30]: df._get_numeric_data()
Out[30]: 
   A         B
0  0 -0.667672
1  1  0.811300
2  2  2.020402
Jeff
sumber
Ya, saya mencoba memikirkan bagaimana mereka melakukan itu. Orang akan mengharapkan fungsi IsNumerik internal berjalan per kolom ... tetapi masih tidak menemukannya di kode
user2808117
Anda dapat menerapkan ini per kolom, tetapi jauh lebih mudah hanya dengan memeriksa dtype-nya. dalam operasi apapun pandas mengecualikan non-numerik bila diperlukan. apa yang sedang Anda coba lakukan?
Jeff
4

Bagaimana kalau hanya memeriksa jenis untuk salah satu nilai di kolom? Kami selalu memiliki sesuatu seperti ini:

isinstance(x, (int, long, float, complex))

Ketika saya mencoba untuk memeriksa tipe data untuk kolom di bawah dataframe, saya mendapatkannya sebagai 'objek' dan bukan tipe numerik yang saya harapkan:

df = pd.DataFrame(columns=('time', 'test1', 'test2'))
for i in range(20):
    df.loc[i] = [datetime.now() - timedelta(hours=i*1000),i*10,i*100]
df.dtypes

time     datetime64[ns]
test1            object
test2            object
dtype: object

Ketika saya melakukan hal berikut, sepertinya memberi saya hasil yang akurat:

isinstance(df['test1'][len(df['test1'])-1], (int, long, float, complex))

kembali

True
Punit S
sumber
1

Anda juga bisa mencoba:

df_dtypes = np.array(df.dtypes)
df_numericDtypes= [x.kind in 'bifc' for x in df_dtypes]

Ini mengembalikan daftar boolean: Truejika numerik, Falsejika tidak.

paulwasit
sumber
1

Hanya untuk menambahkan ke semua jawaban lainnya, seseorang juga dapat menggunakan df.info()untuk mendapatkan tipe data dari setiap kolom.

Beta
sumber
1

Anda dapat memeriksa apakah kolom tertentu berisi nilai numerik atau tidak menggunakan dtypes

numerical_features = [feature for feature in train_df.columns if train_df[feature].dtypes != 'O']

Catatan: "O" harus menjadi huruf kapital

Gokulakrishnan
sumber