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

JSON转PSV时Python去重功能失效问题求助

JSON转PSV去重失效问题排查

我在将JSON文件转换为PSV(竖线分隔文件)时,尝试通过配置文件指定规则去重,但去重功能未生效。以下是实现流程的Python代码,请协助排查问题:

import json
import sys
import csv
from datetime import datetime, timedelta

# function to convert datetime format
def convert_datetime(dt, dt_type):
    if dt_type == 'd':
        return datetime.strptime(dt[:19], '%Y-%m-%dT%H:%M:%S').strftime('%Y-%m-%d')
    elif dt_type == 'fd':
        return datetime.strptime(dt[:23], '%Y-%m-%dT%H:%M:%S.%f').strftime('%Y-%m-%d-%H.%M.%S.%f')

# function to delete duplicates based on specified fields
def delete_duplicate(data, config):
    # sort data based on dupvalue field in descending order
    data.sort(key=lambda x: x[config['dupvalue']], reverse=True)
    
    unique_data = []
    unique_keys = set()
    for d in data:
        key = tuple(d[field] for field in config['fields'])
        if key not in unique_keys:
            unique_data.append(d)
            unique_keys.add(key)
    return unique_data

# read config file
with open(sys.argv[2]) as f:
    config = {}
    for line in f:
        field, value, dt = line.strip().split('|')
        config[field] = value
        config[field + '_dt'] = dt

# read data from json file
with open(sys.argv[1]) as f:
    data = json.load(f)

# extract fields from data
fields = config['fields'] = data[0].keys()

# convert datetime fields
for row in data:
    for field in fields:
        if field + '_dt' in config:
            row[field] = convert_datetime(row[field], config[field + '_dt'])

# delete duplicates
data = delete_duplicate(data, config)

# write data to pipe separated file
with open(sys.argv[3], 'w') as f:
    writer = csv.writer(f, delimiter='|')
    writer.writerow(fields)
    for row in data:
        writer.writerow([row.get(field, 'null') for field in fields])

# add header and tail record with count of data to file
with open(sys.argv[3], 'r') as f:
    lines = f.readlines()

with open(sys.argv[3], 'w') as f:
    f.write('HEADER|{}|{}|{}\n'.format(len(fields), len(data), datetime.now().strftime('%Y-%m-%d %H:%M:%S')))
    f.writelines(lines)
    f.write('TAIL|{}|{}|{}\n'.format(len(fields), len(data), datetime.now().strftime('%Y-%m-%d %H:%M:%S')))

核心问题分析

  • 配置指定的去重字段被强制覆盖:代码先读取配置文件,随后执行config['fields'] = data[0].keys(),直接把配置里定义的去重字段替换成了JSON数据的所有字段。导致delete_duplicate函数用所有字段生成去重键,而非预期的配置指定字段,自然无法按规则去重。

  • dupvalue字段可能未正确配置:delete_duplicate函数依赖config['dupvalue']字段排序来保留优先级最高的记录,如果配置文件未设置该键,或该字段在JSON数据中不存在,会引发KeyError,或导致排序失效,去重后保留的记录不符合预期。

  • 日期转换可能破坏去重键一致性:如果日期转换过程中出现格式错误,同一原始日期值生成不同字符串,会导致本该被判定为重复的记录因键值不同而无法去重。

修复建议

  1. 修正配置读取与字段赋值逻辑:
    不要用data[0].keys()覆盖配置字段,而是从配置文件中提取指定的去重字段。假设配置文件中有一行fields|id,name|,修改配置读取代码:

    # read config file
    with open(sys.argv[2]) as f:
        config = {}
        for line in f:
            field, value, dt = line.strip().split('|')
            if field == 'fields':
                config[field] = value.split(',')
            else:
                config[field] = value
            config[field + '_dt'] = dt
    

    同时删除fields = config['fields'] = data[0].keys(),改为:

    fields = config['fields']
    
  2. 验证dupvalue配置有效性:检查配置文件中是否正确设置了dupvalue对应的字段,且该字段在JSON数据中存在、类型可用于排序(如日期字符串、数字)。

  3. 测试日期转换逻辑:确认同一原始日期值转换后生成一致的字符串,避免因转换错误导致去重键不一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 13:25:01