Snowflake是否自动转换浮点数组为JSON字符串及存储方案咨询
问题描述
我在Snowflake中将部分数据以JSON字符串格式存储,但这些数据实际应为浮点数组。使用UDF将JSON字符串转换为浮点数组后,发现Snowflake内部似乎自动将浮点数组再次转为字符串格式。想知道这是不是Snowflake的默认行为,以及有没有更优方法能以浮点数组的原生格式存储数据,避免每次处理都要执行转换操作。
复现代码
connection_parameters = { "account": "MY_ACCOUNT", "user": "USER", "password": "PASSWORD", "role": "MY_ROLE", "warehouse": "MY_WH", "database": "MY_DB", "schema": "MY_SCHEMA" } table = "MY_TABLE" sf_session = Session.builder.configs(connection_parameters).create()
from snowflake.snowpark.functions import udf, col from snowflake.snowpark.types import ArrayType, DoubleType, StringType import json from typing import List def parse_embedding_from_string(x: str) -> List[float]: res = json.loads(x) return res retrieve_embedding = udf(parse_embedding_from_string) df = sf_session.createDataFrame( data=[ ['[0.4, 2.57, 3.47]'], ['[34.50, 16.34, 12.9]'], ['[413.0, 1.211, 8.41]'], ['[0.4, 8.1, 10.11]'], ['[-6.89, 7.1, -12.1]'], ['[14.0, -21.0, 3.12]'], ['[11.0, 44.1, 26.2]'], ['[-4.4, 5.8, -0.10]'] ], schema=["embedding"] ) df = df.withColumn("embedding_new", retrieve_embedding(col("embedding")))
# 输出 df.toPandas().iloc[0]["EMBEDDING_NEW"]
输出结果:
'[\n 0.4,\n 2.57,\n 3.47\n]'
解决方案
1. 为什么转换后又变成字符串
这不是Snowflake的默认行为,而是因为创建UDF时没有显式指定返回类型。Snowflake无法自动准确推断Python列表对应的Snowflake数据类型,默认将其序列化为JSON字符串返回。
2. 修复UDF的方法
创建UDF时显式指定返回类型为ArrayType(DoubleType()),确保Snowflake识别出这是浮点数组:
retrieve_embedding = udf(parse_embedding_from_string, return_type=ArrayType(DoubleType()))
修改后再执行转换,embedding_new会以原生浮点数组的形式返回,调用df.toPandas()时会直接得到Python列表,而非字符串。
3. 原生存储浮点数组的最优方案
直接使用Snowflake的ARRAY类型存储浮点数组,彻底避免JSON字符串和数组之间的转换操作,提升处理效率:
步骤1:创建带ARRAY类型列的表
CREATE OR REPLACE TABLE MY_TABLE (embedding ARRAY);
步骤2:直接插入浮点数组数据
无需将数组转为JSON字符串,直接传入Python列表即可:
data = [ [[0.4, 2.57, 3.47]], [[34.50, 16.34, 12.9]], [[413.0, 1.211, 8.41]], [[0.4, 8.1, 10.11]], [[-6.89, 7.1, -12.1]], [[14.0, -21.0, 3.12]], [[11.0, 44.1, 26.2]], [[-4.4, 5.8, -0.10]] ] df = sf_session.createDataFrame(data, schema=["embedding"]) df.write.mode("append").saveAsTable("MY_TABLE")
步骤3:查询原生数组
查询时直接获取浮点数组,无需任何转换:
df = sf_session.table("MY_TABLE") print(df.toPandas().iloc[0]["EMBEDDING"]) # 输出:[0.4, 2.57, 3.47]
Snowflake的ARRAY类型原生支持数值元素存储,不仅能避免重复转换的开销,还能直接使用Snowflake内置的数组函数(如ARRAY_SIZE、ARRAY_CONTAINS等)进行数据处理,效率远高于存储JSON字符串。
内容的提问来源于stack exchange,提问作者NikhilKV
相关产品推荐
相关产品推荐

