The*_*o75 1 pandas google-bigquery pyarrow
我有一个熊猫数据框 df:
<bound method NDFrame.head of DAT_RUN DAT_FORECAST LIB_SOURCE MES_LONGITUDE MES_LATITUDE MES_TEMPERATURE MES_HUMIDITE MES_PLUIE MES_VITESSE_VENT MES_U_WIND MES_V_WIND
0 2022-03-29T00:00:00Z 2022-03-29T01:00:00Z gfs_025 43.50 3.75 11.994824 72.0 0.0 2.653137 -2.402910 -1.124792
1 2022-03-29T00:00:00Z 2022-03-29T01:00:00Z gfs_025 43.50 4.00 13.094824 74.3 0.0 2.976434 -2.972910 -0.144792
2 2022-03-29T00:00:00Z 2022-03-29T01:00:00Z gfs_025 43.50 4.25 12.594824 75.3 0.0 3.128418 -2.702910 1.575208
3 2022-03-29T00:00:00Z 2022-03-29T01:00:00Z gfs_025 43.50 4.50 12.094824 75.5 0.0 3.183418 -2.342910 2.155208
Run Code Online (Sandbox Code Playgroud)
我将 DAT_RUN 和 DAT_FORECAST 列转换为日期时间格式:
df["DAT_RUN"] = pd.to_datetime(df['DAT_RUN'], format="%Y-%m-%dT%H:%M:%SZ") # previously "%Y-%m-%d %H:%M:%S"
df["DAT_FORECAST"] = pd.to_datetime(df['DAT_FORECAST'], format="%Y-%m-%dT%H:%M:%SZ")
df.dtypes:
DAT_RUN datetime64[ns]
DAT_FORECAST datetime64[ns]
LIB_SOURCE object
MES_LONGITUDE float64
MES_LATITUDE float64
MES_TEMPERATURE float64
MES_HUMIDITE float64
MES_PLUIE float64
MES_VITESSE_VENT float64
MES_U_WIND float64
MES_V_WIND float64
Run Code Online (Sandbox Code Playgroud)
我使用 bigquery.Client().load_table_from_dataframe() 函数将数据插入 Bigquery 表中,其中数字列具有 NUMERIC bigquery 表。
它返回此错误:
pyarrow.lib.ArrowInvalid: Got bytestring of length 8 (expected 16)
Run Code Online (Sandbox Code Playgroud)
我尝试用以下方法修复它:
df["MES_LONGITUDE"] = df["MES_LONGITUDE"].astype(str).map(decimal.Decimal)
Run Code Online (Sandbox Code Playgroud)
但仅此而已。谢谢。
小智 5
我设法用decimal.Context解决了这个问题,希望它有帮助:
import decimal
import numpy as np
import pandas as pd
from google.cloud import bigquery
df = pd.DataFrame(
data={
"MES_HUMIDITE": np.array([2.653137, 2.976434, 3.128418, 3.183418]),
"MES_PLUIE": np.array([-2.402910, -2.972910, -2.702910, -2.342910]),
},
dtype="float",
)
Run Code Online (Sandbox Code Playgroud)
我们检查数据类型声明:
df.dtypes
# MES_HUMIDITE float64
# MES_PLUIE float64
# dtype: object
Run Code Online (Sandbox Code Playgroud)
初始化Context为 7 位数字,因为它是这些列中的精度,Context如果每列需要不同的精度值,可以创建多个:
context = decimal.Context(prec=7)
df["MES_HUMIDITE"] = df["MES_HUMIDITE"].apply(context.create_decimal_from_float)
df["MES_PLUIE"] = df["MES_PLUIE"].apply(context.create_decimal_from_float)
Run Code Online (Sandbox Code Playgroud)
现在,每个项目都是一个 Decimal 对象:
df["MES_HUMIDITE"][0]
# Decimal('2.653137')
Run Code Online (Sandbox Code Playgroud)
类型已经改变,Pandas 将小数存储为对象,因为我猜这不是原生数据格式:
df.dtypes
# MES_HUMIDITE object
# MES_PLUIE object
# dtype: object
Run Code Online (Sandbox Code Playgroud)
table_id = "test_dataset.test"
job_config = bigquery.LoadJobConfig(
schema=[
bigquery.SchemaField("MES_HUMIDITE", "NUMERIC"),
bigquery.SchemaField("MES_PLUIE", "NUMERIC"),
],
write_disposition="WRITE_TRUNCATE",
)
client = bigquery.Client.from_service_account_json("/path_to_key.json")
job = client.load_table_from_dataframe(df, table_id, job_config=job_config)
job.result()
Run Code Online (Sandbox Code Playgroud)
但是,通常建议在财务计算中使用小数类型,尽管我不知道您的确切情况和用法,但您可能可以安全地使用FLOAT64,至少对于纬度和经度。
| 归档时间: |
|
| 查看次数: |
3242 次 |
| 最近记录: |