[英]How can I cast a Pandas string column to the new nullable Int64 type?
我正在尝试将 Pandas DataFrame 中的字符串列转换为数字列。
我使用以下数据帧:
import pandas as pd
import numpy as np
d = {'col1': ['1', '2'], 'col2': ['5', str(np.nan)], 'col3': [99, str(pd.NA)]}
df = pd.DataFrame(d)
print(df)
col1 col2 col3 0 1 5 99 1 2 nan <NA>
现在,当我将col1
从转换为int
并将col2
为float
,它工作正常:
print(df.col1.astype(int))
print(df.col2.astype(float))
0 1 1 2 Name: col1, dtype: int64 0 5.0 1 NaN Name: col2, dtype: float64
但是当我尝试将col3
从str
为Int64
,出现以下错误:
df.col3.astype(pd.Int64Dtype())
TypeError: object cannot be converted to an IntegerDtype
这是故意的吗?
我怎样才能克服这个限制?
编辑:我编辑了示例数据以使意图更清晰。
更新:
您的示例数据的col3
列具有整数99
和pd.NA
的字符串表示pd.NA
,但您的问题标题询问字符串列。 所以,以防万一你的意思是col3
有一个字符串'99'
和pd.NA
的字符串表示,例如
In [124]: s1 = pd.Series(['99', str(pd.NA)])
In [125]: s1
Out[125]:
0 99
1 <NA>
dtype: object
In [126]: s1.map(type)
Out[126]:
0 <class 'str'>
1 <class 'str'>
dtype: object
在这种情况下,pandas 不允许使用astype
将其直接转换为Int64
。 您需要将pd.to_numeric
与'coerce'
一起使用并转换为Int64
In [130]: s = pd.to_numeric(s1, errors='coerce').astype('Int64')
In [131]: s
Out[131]:
0 99
1 <NA>
dtype: Int64
In [132]: s.map(type)
Out[132]:
0 <class 'int'>
1 <class 'pandas._libs.missing.NAType'>
dtype: object
原文:
在 pandas 1.0.0+ 中,引入了pd.NA
来表示可为空的整数和布尔数据类型以及新的字符串数据类型的缺失值。 当您在pd.NA
上调用str
(即您在col3
数据帧构造函数中调用str(pd.NA)
)时,它返回其字符串表示。 它的字符串表示是字符串<NA>
。
In [84]: pd.NA.__str__()
Out[84]: '<NA>'
它与您在np.nan
上调用str
np.nan
,它的字符串表示是字符串nan
。
In [86]: np.nan.__str__()
Out[86]: 'nan'
因此, col3
实际上没有pd.NA
。 它只包含一个整数99
和一个pd.NA
的字符串表示(即它只是一个普通的字符串<NA>
)。 您想将字符串<NA>
转换为可为空的整数类型Int64
( pd.Int64Dtype()
的别名),因此它会出错。
解决方案:
您需要将此纯字符串<NA>
替换为真正的pd.NA
并转换为Int64
s = df.col3.replace('<NA>', pd.NA).astype('Int64')
Out[57]:
0 99
1 <NA>
Name: col3, dtype: Int64
细节:
col3
的<NA>
显然只是一个普通的字符串
In [64]: df.loc[1, 'col3']
Out[64]: '<NA>'
In [65]: type(df.loc[1, 'col3'])
Out[65]: str
用pd.NA
替换它并pd.NA
为Int64
,它是真正的pd.NA
In [66]: s = df.col3.replace('<NA>', pd.NA).astype('Int64')
In [68]: s[1]
Out[68]: <NA>
In [69]: type(s[1])
Out[69]: pandas._libs.missing.NAType
pandas
DataFrame 带有许多有用的属性。 在处理数字数据类型时, pandas.to_numeric
等pandas.to_numeric
脱颖而出,具有很大的灵活性和简单的语法。
import pandas as pd
import numpy as np
d = {'col1': ['1', '2'], 'col2': ['5', str(np.nan)], 'col3': [99, str(pd.NA)]}
df = pd.DataFrame(d)
to_numeric
需要一1-d array
、 tuple
或Series
print(pd.Series(df['col1']))
# 0 1
# 1 2
# Name: col1, dtype: int64
在处理任意数据时,编写涉及数据类型转换的可靠脚本时,所需的错误处理可能会重复,这由to_numeric
提供
# Looking at data
print(df['col3'].to_string())
# 0 99
# 1 <NA>
# Name: col3, dtype: object
# This line creates error
df['col3'].astype(pd.Int64Dtype())
这会将所有可能的值转换为numeric
,任何不可转换的值将返回input
pd.to_numeric(df['col3'], errors='ignore')
# 0 99
# 1 <NA>
# Name: col3, dtype: object
print(pd.to_numeric([1, 2, 3, 'abc'], errors='ignore'))
# array([1, 2, 3, 'abc'], dtype=object)
将所有可能的值转换为numeric
,任何不可转换的值将作为nan
返回,即( numpy.nan
)
pd.to_numeric(df['col3'], errors='coerce')
# 0 99
# 1 NaN
# Name: col3, dtype: object
print(pd.to_numeric([1, 2, 3, 'abc'], errors='coerce'))
# array([1, 2, 3, nan])
转换所有可能的值并在遇到任何不可转换的值时raise
错误。
pd.to_numeric(df['col3'], errors='raise')
# ValueError: Unable to parse string "<NA>" at position 1
print(pd.to_numeric([1, 2, 3, 'abc'], errors='raise'))
# ValueError: Unable to parse string "abc" at position 3
根据规则(根据文档),它将转换为最小的数据类型
- 'integer' 或 'signed':最小的有符号 int dtype(最小值:np.int8)
- 'unsigned':最小的 unsigned int dtype(最小值:np.uint8)
- 'float': 最小的 float dtype (min.: np.float32)
如果requested
类型大小大于input
,则不进行downcasting
。
# With a = ['1', '2.0', '-3', 4]
pd.to_numeric(a, downcast='integer')
# array([ 1, 2, -3, 4], dtype=int8)
pd.to_numeric(a, downcast='float')
# array([ 1., 2., -3., 4.], dtype=float32)
pd.to_numeric(df['col3'], errors='coerce').astype(pd.Int64Dtype())
请注意, errors='coerce'
返回一个具有float
数据类型的系列。 可以使用astype
数据astype
属性进行转换,因为它是数字数据类型。
实际上浮点数据类型可以包含 NaN 但整数值会抛出错误,如果您的 Pandas 版本低于 v0.24 但从 v0.24 可以包含 NaN 所以你可以尝试
df.col3.astype(pd.Int64Dtype())
或者你可以用一些特定的 no 替换 NaN,然后转换为整数
df.col3.fillna(-1).astype('Int64')
您可以使用对象。
df['col3']=df['col3'].astype(object)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.