选择行时避免类型转换



我有一个带有强制数据类型的DataFrame,这对我的应用程序非常重要:

df = (pd.DataFrame([(1, 1, 1000), 
(1, 2, 2000)], 
columns=['id', 'fk', 'value'])
.astype({'id': pd.Int32Dtype(), 
'fk': pd.Int32Dtype(), 
'value': pd.Float32Dtype()})
df.dtypes.to_dict()

正确的收益率:

{'id': Int32Dtype(), 'fk': Int32Dtype(), 'value': Float32Dtype()}

然而,当我使用.iloc选择一行时,Pandas突然将所有内容强制转换为float——可能是因为它将其转换为一个需要数据类型的系列:

df.iloc[0].dtypes

收益率:

Float64Dtype()

这会导致下游问题,因为我需要正确类型的数据。如何在保持正确类型的同时拉出一行?

您想要从DataFrame:中提取Series(一行(

>>> df
id  fk   value
0   1   1  1000.0  # Int32, Int32, Float32
1   1   2  2000.0
>>> df.iloc[0]
id          1.0
fk          1.0
value    1000.0
Name: 0, dtype: Float64

因此,您有2行Int32和1行Float32。但是,不能混合Series(或DataFrame的列(的数据类型。熊猫必须将你的Series转换成符合你价值观的通用数据类型。这里是Float64

现在是另一种情况:

df = pd.DataFrame([(1, 1, 1000), (1, 2, 2000)], columns=['id', 'fk', 'value']) 
.astype({'id': pd.Int8Dtype(), 'fk': pd.Int16Dtype(), 'value': pd.Int32Dtype()})
>>> df.dtypes
id        Int8
fk       Int16
value    Int32
dtype: object
>>> df.iloc[0]
id          1
fk          1
value    1000
Name: 0, dtype: Int32

在这种情况下,Pandas会找到一个通用的dtype(超集(来封装值。

根据@MichaelSzczesny和@Corralien的评论(谢谢!(,我知道不可能有多个类型的Series,但一行的DataFrame(例如df.iloc[[0]](保留了数据类型。

我现在已经使用它将数据提取到dict中,保留基本数据类型(intfloat等(,这对于我的用例来说已经足够好了:

df.iloc[[0]].to_dict('records')[0]

收益率:

{'id': 1, 'fk': 1, 'value': 1000.0}

最新更新