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

基于另一列值拆分DataFrame列的PostgreSQL数据适配问题

解决PostgreSQL查询返回Decimal列表的dca列拆分问题

问题根源

从PostgreSQL查询得到的dca列并非CSV导入时的字符串格式,而是包含Decimal类型元素的列表:

  • 直接用.str.replace会触发类型错误,因为str方法仅适用于字符串列
  • 强行转字符串后会得到"[Decimal('1.2'), Decimal('3.4')]"这类格式,pd.to_numeric无法识别其中的数值

解决方案

方案1:直接转换Decimal列表为数值列表后拆分

针对dca列是Decimal元素列表的情况,直接遍历列表将每个Decimal转为普通数值,再拆分多列:

import pandas as pd
from decimal import Decimal

# 自定义处理函数,适配原split_dca逻辑
def split_dca(row):
    # 将Decimal列表转为float列表
    dca_nums = [float(x) for x in row['dca']]
    # 按n_mppts截取元素,不足补None
    target_nums = dca_nums[:row['n_mppts']] + [None]*(row['n_mppts'] - len(dca_nums))
    return pd.Series(target_nums)

# 应用函数拆分得到多列
dca_split_cols = df.apply(split_dca, axis=1)
# 给拆分后的列命名
dca_split_cols.columns = [f'dca_{i+1}' for i in range(dca_split_cols.shape[1])]
# 合并到原DataFrame
df = pd.concat([df, dca_split_cols], axis=1)

方案2:正则提取字符串化后的数值

如果dca列已经被转成了"[Decimal('x.x'), ...]"格式的字符串,用正则提取其中的数值部分:

import re
import pandas as pd

def extract_split_dca(row):
    # 提取所有小数/整数数值
    num_strs = re.findall(r'\d+\.?\d*', str(row['dca']))
    dca_nums = [float(s) for s in num_strs]
    # 按n_mppts截取并补全
    target_nums = dca_nums[:row['n_mppts']] + [None]*(row['n_mppts'] - len(dca_nums))
    return pd.Series(target_nums)

# 应用拆分
dca_split_cols = df.apply(extract_split_dca, axis=1)
dca_split_cols.columns = [f'dca_{i+1}' for i in range(dca_split_cols.shape[1])]
df = pd.concat([df, dca_split_cols], axis=1)

方案3:从查询源头转换Decimal类型

在PostgreSQL查询阶段,直接将Decimal类型转为普通数值,避免后续处理:

使用psycopg2连接时,注册适配器将Decimal自动转为字符串(或直接转float):

import psycopg2
from psycopg2.extensions import register_adapter, AsIs
from decimal import Decimal
import pandas as pd

# 注册Decimal适配器,将其转为可直接识别的字符串
def adapt_decimal(dec):
    return AsIs(str(dec))
register_adapter(Decimal, adapt_decimal)

# 连接数据库并查询
conn = psycopg2.connect(host='your_host', dbname='your_db', user='your_user', password='your_pwd')
df = pd.read_sql_query("SELECT * FROM your_table WHERE inverter_id='a2'", conn)
conn.close()

# 此时dca列的列表元素是字符串,直接转数值后拆分
def split_dca(row):
    dca_nums = [float(x) for x in row['dca']]
    target_nums = dca_nums[:row['n_mppts']] + [None]*(row['n_mppts'] - len(dca_nums))
    return pd.Series(target_nums)

dca_split_cols = df.apply(split_dca, axis=1)
dca_split_cols.columns = [f'dca_{i+1}' for i in range(dca_split_cols.shape[1])]
df = pd.concat([df, dca_split_cols], axis=1)

内容的提问来源于stack exchange,提问作者NigelBlainey

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 03:07:04