python pandas read_sql_query使用记录
版本: 系统win 10 ,python 3.5, pandas:0.25.0
解决问题:
读取到的数据为 科学计数法,然后转换成整数影响精度.
pandas 使用 read_sql_query:
pandas.read_sql_query(sql, con, index_col=None, coerce_float=True, params=None, parse_dates=None, chunksize=None)[source]
官方文档:https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_sql_query.html#pandas.read_sql_query
其中:
参数:coerce_float 解释为: 不是字符串类型和 整形 可控制是否强制转换成 float64 类型
场景:
读取数据库数据:
比如:
`test01`
10
32861400000003365
None
读取上述的数据使用 read_sql_query:会自动转换为 float64, 并且读出来的数据是科学计数法,然后使用 astype("int64"),或者读取值进行(int)转换,值会变化(小1),如下模拟数据
int(float(32861400000003365))
Out[8]: 32861400000003364
所以目标是不能被强制转换成 float64,在这种场景下使用 coerce_float 不管是 设置True还是False, 都不起作用,
而 read_sql_query 也没有 dtype 强制设置类型的参数,
后来查源代码;查到转换类型的方法:
文件路径; Python35\Lib\site-packages\pandas\core\internals\construction.py 位置大概在 587行左右
def convert(arr):
if dtype != object and dtype != np.object:
arr = lib.maybe_convert_objects(arr, try_float=coerce_float)
arr = maybe_cast_to_datetime(arr, dtype)
return arr
改成:
def convert(arr):
if dtype != object and dtype != np.object:
if coerce_float:
arr = lib.maybe_convert_objects(arr, try_float=coerce_float)
arr = maybe_cast_to_datetime(arr, dtype)
return arr
- 之后使用 coerce_float 该参数就有效了.
注:
- 当处理数据的时候,
import pandas as pd
def test02():
df = pd.DataFrame({
"A":[32861400000003365,2,None,3],
"B": [1,2,3,4]
})
print(df["A"].dtype,df["B"].dtype)
print(df["A"][0])
test02()
output:
float64 int64
3.2861400000003364e+16
* 有None值,并且不指定类型.pd是会强制转换成float64类型
- 而指定类型后int64:
def test02():
df = pd.DataFrame({
"A":[32861400000003365,2,None,3],
"B": [1,2,3,4]
},dtype="int64")
print(df["A"].dtype,df["B"].dtype)
print(df["A"][0])
test02()
output:
object int64
32861400000003365
因为有None,存在所以会强制转换成字符型(str/object),所以 不指定类型时,
* 确保输入的数字没有None等空值
* 保证转换后的数据不是浮点型
这个时候不指定类型时,不会影响输出
确保输入的数据没有科学计数法,然后强制转成int64数据精度不会丢失,
总结:
- 当输入的数据有 有数字和None 时,使用read_sql_query 中的coerce_float (False) 控制,此时读取 数据是字符型
- 单输入数据有None 数字 字符,这个时候系统应该会强制转换成字符型的,也不会影响输出
- 在读取数据之前,把数据控制好,要么全是数字,要么有字符, 保证输入数据自动转换为int64 类型或者 字符型
- 输入整数控制长度,有None也不会影响结果
以上4种都不会 因为产生 float64 对长整形 的精度 影响