Konversi float ke ints di Pandas?

230

Saya telah bekerja dengan data yang diimpor dari CSV. Panda mengubah beberapa kolom menjadi mengambang, jadi sekarang angka-angka dalam kolom ini ditampilkan sebagai titik mengambang! Namun, saya ingin mereka ditampilkan sebagai bilangan bulat, atau, tanpa koma. Apakah ada cara untuk mengubahnya menjadi bilangan bulat atau tidak menampilkan koma?

MJP
sumber
22
Anda dapat mengubah jenisnya (selama tidak ada nilai yang hilang)df.col = df.col.astype(int)
EdChum
Pertanyaan ini adalah dua pertanyaan sekaligus, dan judul pertanyaan ini hanya mencerminkan satu dari mereka.
Monica Heddneck
Untuk orang yang memukul di atas dan menemukan itu berguna dalam konsep tetapi tidak bekerja untuk Anda, ini adalah versi yang bekerja untuk saya dalam python 3.7.5 dengan panda X:df = df.astype(int)
Oliver.R

Jawaban:

217

Untuk memodifikasi keluaran float, lakukan ini:

df= pd.DataFrame(range(5), columns=['a'])
df.a = df.a.astype(float)
df

Out[33]:

          a
0 0.0000000
1 1.0000000
2 2.0000000
3 3.0000000
4 4.0000000

pd.options.display.float_format = '{:,.0f}'.format
df

Out[35]:

   a
0  0
1  1
2  2
3  3
4  4
EdChum
sumber
16
Terima kasih! Saya menyesuaikan ini di to_csv saya: fin.to_csv ('my_table.csv', float_format = '%. F'). Berhasil!
MJP
4
Dalam versi panda terbaru Anda perlu menambahkan copy = Salah pada argumen astype untuk menghindari peringatan
g.stevo
Apakah itu perlu dilakukan df.a = df.a.astype(float)? Apakah ini membuat salinan (tidak yakin bagaimana copyparam astype()digunakan)? Pokoknya untuk memperbarui jenis "di tempat"?
Mr_and_Mrs_D
1
@ EdChum, adakah cara untuk mencegah Panda dari mengkonversi tipe? Misalnya, coba DF.({'200': {'#': 354, '%': 0.9971830985915493}, '302': {'#': 1, '%': 0.0028169014084507044}}) Perhatikan # dapatkan konversi ke float dan itu adalah baris, bukan kolom. karena masing-masing adalah Seriesyang hanya dapat menyimpan satu jenis seragam?
alancalvitti
@alancalvitti apa niat Anda di sini untuk mempertahankan nilai-nilai atau dtype? Jika itu dtypemaka Anda perlu membuat kolom-kolom dtype objectitu sehingga memungkinkan dicampur, kalau tidak saran saya akan hanya menggunakan float dan ketika melakukan perbandingan gunakannp.isclose
EdChum
180

Menggunakan pandas.DataFrame.astype(<type>) fungsi ini untuk memanipulasi dtypes kolom.

>>> df = pd.DataFrame(np.random.rand(3,4), columns=list("ABCD"))
>>> df
          A         B         C         D
0  0.542447  0.949988  0.669239  0.879887
1  0.068542  0.757775  0.891903  0.384542
2  0.021274  0.587504  0.180426  0.574300
>>> df[list("ABCD")] = df[list("ABCD")].astype(int)
>>> df
   A  B  C  D
0  0  0  0  0
1  0  0  0  0
2  0  0  0  0

EDIT:

Untuk menangani nilai yang hilang:

>>> df
          A         B     C         D
0  0.475103  0.355453  0.66  0.869336
1  0.260395  0.200287   NaN  0.617024
2  0.517692  0.735613  0.18  0.657106
>>> df[list("ABCD")] = df[list("ABCD")].fillna(0.0).astype(int)
>>> df
   A  B  C  D
0  0  0  0  0
1  0  0  0  0
2  0  0  0  0
Ryan G
sumber
3
Saya mencoba pendekatan Anda dan itu memberi saya ValueError: Tidak dapat mengkonversi NA ke integer
MJP
6
@MJP Anda tidak dapat mengubah seri dari float ke integer jika ada nilai yang hilang lihat pandas.pydata.org/pandas-docs/stable/… , Anda harus menggunakan float
EdChum
2
Nilai tidak hilang, tetapi kolom tidak menentukan nilai untuk setiap baris secara sengaja. Apakah ada cara untuk mencapai solusi? Karena nilai-nilai itu adalah id kunci asing, saya perlu ints.
MJP
4
Saya telah mengedit di mana semua NaN diganti dengan 0,0.
Ryan G
3
Atau lebih baik lagi, jika Anda hanya memodifikasi CSV, maka: df.to_csv ("path.csv", na_rep = "", float_format = "%. 0f", index = False) Tapi ini akan mengedit semua float, jadi mungkin lebih baik untuk mengubah kolom FK Anda menjadi string, melakukan manipulasi, dan kemudian menyimpan.
Ryan G
44

Mempertimbangkan kerangka data berikut:

>>> df = pd.DataFrame(10*np.random.rand(3, 4), columns=list("ABCD"))
>>> print(df)
...           A         B         C         D
... 0  8.362940  0.354027  1.916283  6.226750
... 1  1.988232  9.003545  9.277504  8.522808
... 2  1.141432  4.935593  2.700118  7.739108

Menggunakan daftar nama kolom, ubah jenis untuk beberapa kolom dengan applymap():

>>> cols = ['A', 'B']
>>> df[cols] = df[cols].applymap(np.int64)
>>> print(df)
...    A  B         C         D
... 0  8  0  1.916283  6.226750
... 1  1  9  9.277504  8.522808
... 2  1  4  2.700118  7.739108

Atau untuk satu kolom dengan apply():

>>> df['C'] = df['C'].apply(np.int64)
>>> print(df)
...    A  B  C         D
... 0  8  0  1  6.226750
... 1  1  9  9  8.522808
... 2  1  4  2  7.739108
Jaroslav Bezděk
sumber
5
Bagaimana jika ada nilai NaN?
Zhang18
3
@ Zhang18 Saya mencoba solusi ini dan dalam kasus NaN Anda memiliki kesalahan ini:ValueError: ('cannot convert float NaN to integer', u'occurred at index <column_name>')
Enri
2
@ enri: Dapat mencoba kode berikut -df['C'] = df['C'].dropna().apply(np.int64)
vsdaking
12

Ini adalah solusi cepat jika Anda ingin mengkonversi lebih banyak kolom pandas.DataFramedari float ke integer dengan mempertimbangkan juga kasus bahwa Anda dapat memiliki nilai NaN.

cols = ['col_1', 'col_2', 'col_3', 'col_4']
for col in cols:
   df[col] = df[col].apply(lambda x: int(x) if x == x else "")

Saya mencoba dengan else x)dan else None), tetapi hasilnya masih memiliki nomor float, jadi saya gunakan else "".

enri
sumber
itu akan berlaku ""untuk semua nilai dicol
Raheel
Ini akan menerapkan string kosong ("") ke semua nilai yang hilang, jika itu yang diperlukan, tetapi nilai-nilai lainnya akan menjadi bilangan bulat.
Krzysztof Słowiński
Terima kasih untuk ini. Ini berfungsi ketika .astype () dan .apply (np.int64) tidak.
Alison S
Ini terasa berantakan, dan saya tidak melihat alasan untuk menggunakannya di atas banyak alternatif yang tersedia.
AMC
8

Memperluas pada @Ryan G menyebutkan penggunaan pandas.DataFrame.astype(<type>)metode ini, orang dapat menggunakan errors=ignoreargumen untuk hanya mengonversi kolom-kolom yang tidak menghasilkan kesalahan, yang terutama menyederhanakan sintaksis. Jelas, kehati-hatian harus diterapkan ketika mengabaikan kesalahan, tetapi untuk tugas ini sangat berguna.

>>> df = pd.DataFrame(np.random.rand(3, 4), columns=list('ABCD'))
>>> df *= 10
>>> print(df)
...           A       B       C       D
... 0   2.16861 8.34139 1.83434 6.91706
... 1   5.85938 9.71712 5.53371 4.26542
... 2   0.50112 4.06725 1.99795 4.75698

>>> df['E'] = list('XYZ')
>>> df.astype(int, errors='ignore')
>>> print(df)
...     A   B   C   D   E
... 0   2   8   1   6   X
... 1   5   9   5   4   Y
... 2   0   4   1   4   Z

Dari pandas.DataFrame.astype docs:

kesalahan: {'naikkan', 'abaikan'}, default 'naikkan'

Mengontrol peningkatan pengecualian pada data yang tidak valid untuk tipe yang disediakan.

  • naikkan: izinkan pengecualian dimunculkan
  • abaikan: menekan pengecualian. Pada kesalahan mengembalikan objek asli

Baru dalam versi 0.20.0.

aebmad
sumber
7
>>> import pandas as pd
>>> right = pd.DataFrame({'C': [1.002, 2.003], 'D': [1.009, 4.55], 'key': ['K0', 'K1']})
>>> print(right)
           C      D key
    0  1.002  1.009  K0
    1  2.003  4.550  K1
>>> right['C'] = right.C.astype(int)
>>> print(right)
       C      D key
    0  1  1.009  K0
    1  2  4.550  K1
pengguna8051244
sumber
5

Untuk mengkonversi semua kolom float ke int

>>> df = pd.DataFrame(np.random.rand(5, 4) * 10, columns=list('PQRS'))
>>> print(df)
...     P           Q           R           S
... 0   4.395994    0.844292    8.543430    1.933934
... 1   0.311974    9.519054    6.171577    3.859993
... 2   2.056797    0.836150    5.270513    3.224497
... 3   3.919300    8.562298    6.852941    1.415992
... 4   9.958550    9.013425    8.703142    3.588733

>>> float_col = df.select_dtypes(include=['float64']) # This will select float columns only
>>> # list(float_col.columns.values)
>>> for col in float_col.columns.values:
...     df[col] = df[col].astype('int64')
>>> print(df)
...     P   Q   R   S
... 0   4   0   8   1
... 1   0   9   6   3
... 2   2   0   5   3
... 3   3   8   6   1
... 4   9   9   8   3
Suhas_Pote
sumber
0

Berikut adalah fungsi sederhana yang akan mengirim data mengambang ke tipe integer sekecil mungkin yang tidak kehilangan informasi apa pun. Sebagai contoh,

  • 100.0 dapat dikonversi dari float ke integer, tetapi 99.9 tidak dapat (tanpa kehilangan informasi menjadi pembulatan atau pemotongan)

  • Selain itu, 1.0 dapat di-downcast sepenuhnya int8tanpa kehilangan informasi, tetapi tipe integer terkecil untuk 100_000.0 adalahint32

Contoh kode:

import numpy as np
import pandas as pd

def float_to_int( s ):
    if ( s.astype(np.int64) == s ).all():
        return pd.to_numeric( s, downcast='integer' )
    else:
        return s

# small integers are downcast into 8-bit integers
float_to_int( np.array([1.0,2.0]) )
Out[1]:array([1, 2], dtype=int8)

# larger integers are downcast into larger integer types
float_to_int( np.array([100_000.,200_000.]) )
Out[2]: array([100000, 200000], dtype=int32)

# if there are values to the right of the decimal
# point, no conversion is made
float_to_int( np.array([1.1,2.2]) )
Out[3]: array([ 1.1,  2.2])
JohnE
sumber
0

Kolom yang perlu dikonversi ke int dapat disebutkan dalam kamus juga seperti di bawah ini

df = df.astype({'col1': 'int', 'col2': 'int', 'col3': 'int'})
prashanth
sumber
-5
>>> df_18['cyl'].value_counts()
... 4.0     365
... 6.0     246
... 8.0     153

>>> df_18['cyl'] = df_18['cyl'].astype(int)
>>> df_18['cyl'].value_counts()
... 4     365
... 6     246
... 8     153
RAHUL KUMAR
sumber
1
astype(int)sudah disebutkan beberapa kali. Jawaban ini tidak menambahkan sesuatu yang baru.
Georgy