You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 04:06:13