Hive/Bigsql Pandas 将浮点数转换为整数,使用 pyarrow 将空值转换为镶木地板文件

Posted

技术标签:

【中文标题】Hive/Bigsql Pandas 将浮点数转换为整数,使用 pyarrow 将空值转换为镶木地板文件【英文标题】:Hive/Bigsql pandas float cast to integer with nulls into parquet file with pyarrow 【发布时间】:2021-03-06 15:55:16 【问题描述】:

我对 pandas、pyarrow 和 bigsql 有疑问。基本上我想读取 csv ,将其写入 parquet 并从 db 读取 parquet。但是从db读取文件时出现问题。 Pandas dtype 和 db 数据类型不一样。

在 bigsql 中创建了一个表,例如:

CREATE EXTERNAL hadoop TABLE sch.test (
  id bigint ,
  integer_column integer
)

我有 csv 文件并将其加载到 pandas 中

csv = pd.read_csv(x)
print(csv.head(20))

           id          integer_column 
0      200001                     0.0
1      200002                     0.0
2      200003                     0.0
3      200004                     0.0
4      200005                     0.0
5      200006                     0.0
6      200007                     0.0
7      200008                     0.0
8      200009                     0.0
9      200010                     0.0
10     200011                     0.0
11     200012                     0.0
12     200013                     0.0
13     200014                     0.0
14     200015                     0.0
15     200016                     NaN
16     200017                     NaN
17     200018                     NaN
18     200019                     NaN
19     200020                     NaN

纯 csv 是这样的

id,integer_column 
200001,0.0
200002,0.0
200016,

然后我尝试通过 pyarrow.parquet.ParquetWriter 之类的方式编写镶木地板文件

    import pyarrow.parquet as pq
    csv = pd.read_csv(x)
    table = pa.Table.from_pandas(csv)
    pqwriter = pq.ParquetWriter('./filename.prq', table.schema,coerce_timestamps='ms', \
               allow_truncated_timestamps=True,flavor='spark')            
    pqwriter.write_table(table)
    pqwriter.close()
    print(pa.Schema.from_pandas(csv ))
id: int64
integer_column : double
metadata
--------
b'pandas': b'"index_columns": ["kind": "range", "name": null, "start": 0, "'
            b'stop": 25000, "step": 1], "column_indexes": ["name": null, "fi'
            b'eld_name": null, "pandas_type": "unicode", "numpy_type": "object'
            b'", "metadata": "encoding": "UTF-8"], "columns": ["name": "id
            b, "field_name": "id", "pandas_type": "int64", "nu'
            b'mpy_type": "int64", "metadata": null, "name": "integer_column '
            b'medelta", "field_name": "integer_column", "pandas_type":'
            b' "float64", "numpy_type": "float64", "metadata": null], "creato'
            b'r": "library": "pyarrow", "version": "0.15.1", "pandas_version'
            b'": "0.25.3"'

所以我想将其 integer_column 转换为整数并摆脱浮点数,然后将其写入 hive/bigsql 能够读取的 parquet。 当我像我显示的那样插入它时出现错误:

大SQL: he 语句失败,因为 Big SQL 组件遇到错误。收到错误的组件:“BigSQL IO”。返回错误的组件:“未知”。 SQLCODE=-5105, SQLSTATE=58040

蜂巢: SQL 错误:java.io.IOException: org.apache.hadoop.hive.ql.metadata.HiveException: java.lang.ClassCastException: org.apache.hadoop.hive.serde2.io.DoubleWritable 不能转换为 org.apache。 hadoop.io.IntWritable

我不能强制 pandas 或 pyarrow 正确地将 double 转换为整数。我知道它是双重的,因为有空值和它的熊猫自然行为,但是我怎样才能将它作为具有空值的整数正确插入到 db 中?

唯一可行的解​​决方案是将 db 列更改为 double 类型或在此 pandas 列上设置 fillna(0).astype(np.int32) - 但我在这里丢失了信息。

如果您有任何想法,请分享您的知识。 谢谢。

解决: pandas/pyarrow 升级和下面的代码有所帮助。

csv['integer_column'] = csv['integer_column'].astype('Int64')

【问题讨论】:

【参考方案1】:

Pandas 0.24.0 及更高版本支持可为空的整数列,因此您可以在 pandas 中进行转换。

csv['integer_column'] = csv['integer_column'].astype('Int64')

或者您可以使用 pyarrow 计算函数在 pyarrow 中将 float 转换为 int。

table = table.set_column(1, table.column_names[1], pc.cast(table.column(1), pa.int64()))

【讨论】:

基本上它有所帮助,但仅适用于 bigsql。 Hiveserver 仍然无法加载此值。错误:SQL 错误:java.io.IOException:org.apache.hadoop.hive.ql.metadata.HiveException:java.lang.ClassCastException:org.apache.hadoop.io.LongWritable 无法转换为 org.apache.hadoop。 io.IntWritable。此列具有最大值print(selected['integer_column'].max())4534 我不知道为什么 hive 无法将其加载为整数。当我将列数据类型更改为 bigint 时,当然一切都消失了。

以上是关于Hive/Bigsql Pandas 将浮点数转换为整数,使用 pyarrow 将空值转换为镶木地板文件的主要内容,如果未能解决你的问题,请参考以下文章

Python如何将浮点数作为十六进制转换为十进制

Pandas 将浮点数附加到 for 循环中的列

Javascript将浮点数转换为指数[重复]

将浮点数转换为美元和美分

C将浮点数转换为int

使用 . 将浮点数转换为字符串。而不是 , [重复]