Dataframe切片中的一些细节(坑)——整型变浮点,返回Series还是Dataframe?

场景例程:

with db.cursor() as c1:
    sql='''select 原料1原料筒,原料2原料筒,原料3原料筒,原料1比例,原料2比例,原料3比例
from 配方表 where 配方号=%s;'''
    c1.execute(sql,pf_no)
    if c1.rowcount>0:
        data=pd.DataFrame(c1.fetchall())
        t_exe=data.iloc[0,:3]
        bl_exe=data.iloc[0,3:]

这里原料筒在数据库的数据类型是int,原料比例的数据类型是float,原本期望得到一个整型Series(t_exe)和一个浮点型Series(bl_exe),然而在实际应用中报错,调试中发现t_exe中的数据类型全部变成了浮点型。

data=pd.DataFrame(c1.fetchall())
data.iloc[0,:3]
Out[20]: 
0    3.0
1    1.0
2    2.0
Name: 0, dtype: float64

而采用t_exe=data.iloc[:1,:3]时,数据类型没变:

data.iloc[:1,:3]
Out[22]: 
   0  1  2
0  3  1  2

原因:

t_exe=data.iloc[0,:3]

当执行t_exe=data.iloc[0,:3]时,Pandas提取出DataFrame的第一行的前三列并创建了一个Series对象。在Pandas中,Series默认倾向于使用较为通用的数据类型来存储数据,以适应可能存在的不同数据类型。对于数值型数据,如果没有明确指定或数据中存在非整数值(如浮点数),Pandas可能会自动将整个Series的数据类型提升为float64,以避免信息丢失。

t_exe=data.iloc[:1,:3]

而当执行t_exe=data.iloc[:1,:3]时,得到的是一个包含单行(第一行)但仍然是DataFrame格式的结果。DataFrame在处理数据时,对于每一列,它会尝试保持原始数据类型,只要该类型在DataFrame的列中是同质的。因此,如果原始数据库查询结果中前三列确实是整型,且没有浮点数混入,Pandas在构建这个小的DataFrame时,会保留整型。

解决办法

如果希望在提取Series时也保持原始的整型数据,可以显式地设置数据类型。例如:

t_exe=data.iloc[0,:3].apply(int)
或
t_exe=data.iloc[0,:3].astype(int)

也可以在得到小的Dataframe后再做一次切片

data.iloc[:1,:3].iloc[0]
Out[25]: 
0    3
1    1
2    2
Name: 0, dtype: int64

这里还有一个小的知识点:在大多数情况下,将Pandas的Series对象用于预期接收列表或其他一维数据集合的函数或方法时,不会直接报错,因为Series设计为与这些场景兼容,所以很多时候需要列表的地方可以直接用Series类型,即直接切片出的单行或单列。但!!!用data.iloc[:1,:3]切出来的单行单列直接当列表用会报错,因为它的数据格式仍然是DataFrame,这是pandas为了保持数据一致性所进行的处理。

  • 7
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南瓜鹅鹅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值