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.


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

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

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


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'])

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

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

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.


1

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


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

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.