Pandas:将数据类型“object”转换为int
- 2025-04-16 08:57:00
- admin 原创
- 15
问题描述:
我已经将一个 SQL 查询读入 Pandas,虽然值是字符串、日期和整数,但其数据类型却是“object”。我能够将日期“object”转换为 Pandas 的 datetime 数据类型,但在尝试转换字符串和整数时出现错误。
以下是一个例子:
>>> import pandas as pd
>>> df = pd.read_sql_query('select * from my_table', conn)
>>> df
id date purchase
1 abc1 2016-05-22 1
2 abc2 2016-05-29 0
3 abc3 2016-05-22 2
4 abc4 2016-05-22 0
>>> df.dtypes
id object
date object
purchase object
dtype: object
将其转换df['date']
为日期时间有效:
>>> pd.to_datetime(df['date'])
1 2016-05-22
2 2016-05-29
3 2016-05-22
4 2016-05-22
Name: date, dtype: datetime64[ns]
df['purchase']
但是当我尝试将其转换为整数时出现错误:
>>> df['purchase'].astype(int)
....
pandas/lib.pyx in pandas.lib.astype_intsafe (pandas/lib.c:16667)()
pandas/src/util.pxd in util.set_value_at (pandas/lib.c:67540)()
TypeError: long() argument must be a string or a number, not 'java.lang.Long'
注意:当我尝试时我得到了类似的错误.astype('float')
当尝试转换为字符串时,似乎什么也没有发生。
>>> df['id'].apply(str)
1 abc1
2 abc2
3 abc3
4 abc4
Name: id, dtype: object
解决方案 1:
根据@piRSquared 的评论记录对我有用的答案。
我需要先转换为字符串,然后再转换为整数。
>>> df['purchase'].astype(str).astype(int)
解决方案 2:
熊猫> = 1.0
convert_dtypes
(自我)接受的答案没有考虑到对象列中存在 NaN 的可能性。
df = pd.DataFrame({
'a': [1, 2, np.nan],
'b': [True, False, np.nan]}, dtype=object)
df
a b
0 1 True
1 2 False
2 NaN NaN
df['a'].astype(str).astype(int) # raises ValueError
这会导致错误,因为 NaN 会被转换为字符串“nan”,进一步尝试强制转换为整数将会失败。为了避免这个问题,我们可以使用以下命令将列软转换为其对应的可空类型convert_dtypes
:
df.convert_dtypes()
a b
0 1 True
1 2 False
2 <NA> <NA>
df.convert_dtypes().dtypes
a Int64
b boolean
dtype: object
如果您的数据中有垃圾文本与整数混合,您可以使用以下方法pd.to_numeric
作为初始步骤:
s = pd.Series(['1', '2', '...'])
s.convert_dtypes() # converts to string, which is not what we want
0 1
1 2
2 ...
dtype: string
# coerces non-numeric junk to NaNs
pd.to_numeric(s, errors='coerce')
0 1.0
1 2.0
2 NaN
dtype: float64
# one final `convert_dtypes` call to convert to nullable int
pd.to_numeric(s, errors='coerce').convert_dtypes()
0 1
1 2
2 <NA>
dtype: Int64
解决方案 3:
df['col_name'] = pd.to_numeric(df['col_name'])
这是一个更好的选择
解决方案 4:
我的训练数据包含三个特征,应用后将astype
对象转换为数字,但在此之前,您需要执行一些预处理步骤:
train.dtypes
C12 object
C13 object
C14 Object
train['C14'] = train.C14.astype(int)
train.dtypes
C12 object
C13 object
C14 int32
解决方案 5:
很简单
pd.factorize(df.purchase)[0]
例子:
labels, uniques = pd.factorize(['b', 'b', 'a', 'c', 'b'])`
labels
# array([0, 0, 1, 2, 0])
uniques
# array(['b', 'a', 'c'], dtype=object)
解决方案 6:
要更改数据类型并将其保存到数据框中,需要按如下方式替换新的数据类型:
ds["cat"] = pd.to_numeric(ds["cat"])
或者
ds["cat"] = ds["cat"].astype(int)
解决方案 7:
请按照以下步骤操作:
1.清理您的文件->以csv
格式打开您的数据文件,查看空白处是否有“?”并将其全部删除。
2.删除包含缺失值的行,例如:
df.dropna(subset=["normalized-losses"], axis = 0 , inplace= True)
3.现在使用 astype 进行转换
df["normalized-losses"]=df["normalized-losses"].astype(int)
注意:如果仍然在程序中发现错误,请再次检查您的csv
文件,在 Excel 中打开它以查找所需的列中是否有“?”,然后将其删除并保存文件,然后返回并运行您的程序。
评论成功!如果有效的话。:)
解决方案 8:
无法评论,因此将其作为答案发布,该答案介于@piRSquared / @cyril的解决方案和@cs95的解决方案之间:
正如@cs95 所指出的,如果您的数据包含 NaN 或 None,则在转换为字符串类型后尝试转换为 int 时会引发错误。
但是,如果您的数据由(数字)字符串组成,则使用convert_dtypes
会将其转换为字符串类型,除非您pd.to_numeric
按照@cs95 的建议使用(可能与结合df.apply()
)。
如果您的数据仅由数字字符串组成(包括 NaN 或 None 但没有任何非数字“垃圾”),则可能更简单的替代方法是先将其转换为浮点数,然后将其转换为pandas 提供的可空整数扩展数据类型之一(已存在于 0.24 版中)(另请参阅此答案):
df['purchase'].astype(float).astype('Int64')
请注意, github上最近对此进行了讨论(尽管目前是一个未解决的已关闭问题),并且对于非常长的 64 位整数,您可能必须明确转换为float128
以避免在转换过程中出现近似值。
解决方案 9:
如果这些方法失败,您可以尝试如下列表推导:
df["int_column"] = [int(x) if x.isnumeric() else x for x in df["str_column"] ]
解决方案 10:
就我而言,我有一个包含混合数据的 df:
df:
0 1 2 ... 242 243 244
0 2020-04-22T04:00:00Z 0 0 ... 3,094,409.5 13,220,425.7 5,449,201.1
1 2020-04-22T06:00:00Z 0 0 ... 3,716,941.5 8,452,012.9 6,541,599.9
....
浮点数实际上是物体,但我需要它们是真正的浮点数。
要修复此问题,请参考上面@AMC 的评论:
def coerce_to_float(val):
try:
return float(val)
except ValueError:
return val
df = df.applymap(lambda x: coerce_to_float(x))
解决方案 11:
将对象转换为数值int
或float
。
代码是:--
df["total_sqft"] = pd.to_numeric(df["total_sqft"], errors='coerce').fillna(0, downcast='infer')
解决方案 12:
使用 astype 函数转换该列的数据类型
解决方案 13:
这是我的数据
## list of columns
l1 = ['PM2.5', 'PM10', 'TEMP', 'BP', ' RH', 'WS','CO', 'O3', 'Nox', 'SO2']
for i in l1:
for j in range(0, 8431): #rows = 8431
df[i][j] = int(df[i][j])
我建议你只在数据量较小的情况下使用这个方法。此代码的复杂度为 O(n^2)。
扫码咨询,免费领取项目管理大礼包!