Chuyển đổi float thành ints trong Pandas?


230

Tôi đã làm việc với dữ liệu được nhập từ CSV. Gấu trúc đã thay đổi một số cột thành float, vì vậy bây giờ các số trong các cột này được hiển thị dưới dạng các điểm nổi! Tuy nhiên, tôi cần chúng được hiển thị dưới dạng số nguyên hoặc không có dấu phẩy. Có cách nào để chuyển đổi chúng thành số nguyên hay không hiển thị dấu phẩy?


22
Bạn có thể thay đổi loại (miễn là không có giá trị bị thiếu)df.col = df.col.astype(int)
EdChum

Câu hỏi này là hai câu hỏi cùng một lúc và tiêu đề của câu hỏi này chỉ phản ánh một trong số chúng.
Monica Heddneck

Đối với một người đánh vào những điều trên và thấy nó hữu ích trong khái niệm nhưng không hiệu quả với bạn, đây là phiên bản phù hợp với tôi trong python 3.7.5 với gấu trúc X:df = df.astype(int)
Oliver.R

Câu trả lời:


217

Để sửa đổi đầu ra float, hãy làm điều này:

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

16
Cảm ơn! Tôi đã điều chỉnh điều này trong to_csv: fin.to_csv ('my_table.csv', float_format = '%. F'). Nó đã làm việc!
MJP

4
Trong phiên bản mới nhất của gấu trúc, bạn cần thêm bản sao = Sai vào các đối số của astype để tránh cảnh báo
g.stevo

Có cần phải làm gì df.a = df.a.astype(float)không? Điều này có tạo ra một bản sao (không chắc cách sử dụng copyparam astype())? Dù sao để cập nhật loại "tại chỗ"?
Mr_and_Mrs_D

1
@EdChum, có cách nào để ngăn chặn Pandas chuyển đổi các loại để bắt đầu không? Ví dụ: thử DF.({'200': {'#': 354, '%': 0.9971830985915493}, '302': {'#': 1, '%': 0.0028169014084507044}}) Lưu ý # get convert thành float và chúng là các hàng, không phải cột. bởi vì mỗi Seriescái chỉ có thể lưu trữ một loại đồng phục duy nhất?
alancalvitti

@alancalvitti ý định của bạn ở đây là gì để bảo tồn các giá trị hay dtype? Nếu đó là dtypelúc bạn cần tạo các cột dtype objectđó để nó cho phép trộn, nếu không, lời khuyên của tôi là chỉ sử dụng float và khi thực hiện so sánh sử dụngnp.isclose
EdChum

180

Sử dụng pandas.DataFrame.astype(<type>)hàm để thao tác các dtypes cột.

>>> 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

BIÊN TẬP:

Để xử lý các giá trị còn thiếu:

>>> 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

3
Tôi đã thử cách tiếp cận của bạn và nó mang lại cho tôi một ValueError: Không thể chuyển đổi NA thành số nguyên
MJP

6
@MJP Bạn không thể chuyển đổi chuỗi từ float sang số nguyên nếu thiếu các giá trị, xem pandas.pydata.org/pandas-docs/ sóng / trộm , bạn phải sử dụng float
EdChum

2
Các giá trị không bị thiếu, nhưng cột không chỉ định giá trị cho từng hàng theo mục đích. Có cách nào để đạt được một cách giải quyết? Vì các giá trị này là id khóa ngoại, tôi cần ints.
MJP

4
Tôi đã thực hiện chỉnh sửa trong đó tất cả các NaN được thay thế bằng 0,0.
Ryan G

3
Hoặc tốt hơn nữa, nếu bạn chỉ sửa đổi CSV, thì: df.to_csv ("path.csv", na nump = "", float_format = "%. 0f", index = Sai) Nhưng điều này sẽ chỉnh sửa tất cả các float có thể tốt hơn để chuyển đổi cột FK của bạn thành một chuỗi, thực hiện các thao tác và sau đó lưu lại.
Ryan G

44

Xem xét khung dữ liệu sau:

>>> 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

Sử dụng danh sách tên cột, thay đổi loại cho nhiều cột bằng 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

Hoặc cho một cột duy nhất với 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

5
Nếu có NaN trong giá trị thì sao?
Zhang18

3
@ Zhang18 Tôi đã thử giải pháp này và trong trường hợp NaN bạn có lỗi này:ValueError: ('cannot convert float NaN to integer', u'occurred at index <column_name>')
enri

2
@enri: Có thể thử đoạn mã sau -df['C'] = df['C'].dropna().apply(np.int64)
so với

12

Đây là một giải pháp nhanh chóng trong trường hợp bạn muốn chuyển đổi nhiều cột của bạn pandas.DataFrametừ float sang số nguyên cũng xem xét trường hợp bạn có thể có các giá trị 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 "")

Tôi đã thử với else x)else None), nhưng kết quả vẫn có số float, vì vậy tôi đã sử dụng else "".


nó sẽ áp dụng ""cho tất cả các giá trị trongcol
Raheel

Nó sẽ áp dụng chuỗi rỗng ("") cho tất cả các giá trị còn thiếu, nếu đó là những gì được yêu cầu, nhưng phần còn lại của các giá trị sẽ là số nguyên.
Krzysztof Słowiński

Cảm ơn vì điều đó. Điều này hoạt động khi .astype () và .apply (np.int64) không hoạt động.
Alison S

Điều này cảm thấy khó khăn và tôi thấy không có lý do gì để sử dụng nó trong nhiều lựa chọn thay thế có sẵn.
AMC

8

Mở rộng trên @Ryan G đã đề cập đến việc sử dụng pandas.DataFrame.astype(<type>)phương thức, người ta có thể sử dụng errors=ignoređối số để chỉ chuyển đổi các cột không tạo ra lỗi, điều này làm đơn giản hóa cú pháp. Rõ ràng, nên thận trọng khi bỏ qua lỗi, nhưng đối với nhiệm vụ này, nó rất tiện dụng.

>>> 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

Từ tài liệu pandas.DataFrame.astype :

lỗi: {'nâng cao', 'bỏ ​​qua'}, mặc định 'nâng cao'

Kiểm soát nâng cao các ngoại lệ trên dữ liệu không hợp lệ cho dtype được cung cấp.

  • nâng cao: cho phép ngoại lệ được nêu ra
  • bỏ qua: triệt tiêu các ngoại lệ. Khi lỗi trả về đối tượng ban đầu

Mới trong phiên bản 0.20.0.


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

5

Để chuyển đổi tất cả các cột float sang 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

0

Đây là một hàm đơn giản giúp downcast nổi vào loại số nguyên nhỏ nhất có thể mà không mất bất kỳ thông tin nào. Ví dụ như,

  • 100.0 có thể được chuyển đổi từ float sang số nguyên, nhưng 99.9 không thể (mà không mất thông tin để làm tròn hoặc cắt bớt)

  • Ngoài ra, 1.0 có thể được downcast tất cả các cách int8mà không làm mất thông tin, nhưng loại số nguyên nhỏ nhất cho 100_000.0 làint32

Mã ví dụ:

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

0

Các cột cần được chuyển đổi thành int cũng có thể được đề cập trong từ điển như dưới đây

df = df.astype({'col1': 'int', 'col2': 'int', 'col3': 'int'})

-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

1
astype(int)đã được đề cập nhiều lần. Câu trả lời này không thêm bất cứ điều gì mới.
Georgy
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.