Python嵌套数组处理方案抉择:本地处理还是导入MySQL?
两种方案实现你的数据筛选需求
一、直接用Python处理数组
完全可以在Python里高效实现你的规则,不用依赖数据库,步骤如下:
步骤1:按(symbol, direction)分组,保留每组杠杆最大的条目
先用字典分组,遍历数据时只保留每个(symbol, direction)组合下杠杆最高的记录:
datas = [ ['Anonymous User-b82a42', 'DYDXUSDT', 'Short', 20, 258.2, 2.332, 2.333, -0.26, -0.8573, '2022-11-16 14:02:28'], ['Anonymous User-b82a42', 'OCEANUSDT', 'Long', 20, 4732.0, 0.13113, 0.13145, 1.51, 4.8688, '2022-11-16 09:04:04'], ['Anonymous User-b82a42', 'CHZUSDT', 'Short', 20, 2684.0, 0.22187, 0.22637, -12.08, -39.7579, '2022-11-16 11:10:17'], ['Anonymous User-b82a42', 'DUSKUSDT', 'Long', 20, 6636.0, 0.09043, 0.09007, -2.38, -7.9724, '2022-11-16 12:40:17'], ['Anonymous User-b82a42', 'CTSIUSDT', 'Long', 20, 5614.0, 0.1062, 0.1058, -2.22, -7.4594, '2022-11-16 13:47:25'], # 模拟测试数据:同一symbol不同direction且杠杆相同的情况 ['Anonymous User-b82a42', 'TESTUSDT', 'Long', 15, 100.0, 0.5, 0.51, 2.0, 6.0, '2022-11-16 10:00:00'], ['Anonymous User-b82a42', 'TESTUSDT', 'Short', 15, 200.0, 0.49, 0.5, -2.0, -6.0, '2022-11-16 11:00:00'] ] # 第一步:按(symbol, direction)分组,保留杠杆最大的条目 grouped = {} for item in datas: symbol = item[1] direction = item[2] leverage = item[3] key = (symbol, direction) # 如果键不存在,或者当前条目的杠杆更大,就更新 if key not in grouped or leverage > grouped[key][3]: grouped[key] = item # 转换为列表,此时已经满足规则1和2 filtered_step1 = list(grouped.values()) # 第二步:处理规则3:同一symbol下相反direction且杠杆相同的,全部移除 # 先按symbol分组,统计每个symbol下的direction和对应的杠杆 symbol_map = {} for item in filtered_step1: symbol = item[1] direction = item[2] leverage = item[3] if symbol not in symbol_map: symbol_map[symbol] = {} symbol_map[symbol][direction] = item # 筛选最终结果 final_result = [] for symbol, dir_items in symbol_map.items(): # 如果symbol下有两个方向,且杠杆相同,跳过 if len(dir_items) == 2: long_leverage = dir_items.get('Long', [])[3] if 'Long' in dir_items else None short_leverage = dir_items.get('Short', [])[3] if 'Short' in dir_items else None if long_leverage == short_leverage: continue # 否则保留两个条目 final_result.extend(dir_items.values()) else: # 只有一个方向,直接保留 final_result.extend(dir_items.values()) # 输出结果 for res in final_result: print(res)
代码说明:
- 第一阶段用字典分组,一次遍历就能完成规则1和2的筛选,时间复杂度O(n),效率很高
- 第二阶段检查每个symbol下的多方向记录,处理规则3的删除逻辑
二、用MySQL处理
如果你的数据量很大(比如百万级以上),或者后续需要频繁做复杂查询,导入MySQL处理更合适,步骤如下:
步骤1:建表并导入数据
先创建对应数据表:
CREATE TABLE trade_records ( id INT AUTO_INCREMENT PRIMARY KEY, user VARCHAR(50), symbol VARCHAR(20), direction VARCHAR(10), leverage INT, col5 DECIMAL(10,2), col6 DECIMAL(10,5), col7 DECIMAL(10,5), col8 DECIMAL(10,2), col9 DECIMAL(10,4), create_time DATETIME );
然后把Python数组中的数据批量插入到这个表中。
步骤2:用SQL语句完成筛选
用窗口函数先筛选每个(symbol, direction)组内杠杆最大的记录,再过滤掉同一symbol下相反方向杠杆相同的记录:
WITH ranked_records AS ( SELECT *, ROW_NUMBER() OVER (PARTITION BY symbol, direction ORDER BY leverage DESC) AS rn FROM trade_records ), filtered_step1 AS ( SELECT * FROM ranked_records WHERE rn = 1 ), symbol_leverage_check AS ( SELECT symbol, MAX(CASE WHEN direction = 'Long' THEN leverage END) AS long_leverage, MAX(CASE WHEN direction = 'Short' THEN leverage END) AS short_leverage, COUNT(DISTINCT direction) AS dir_count FROM filtered_step1 GROUP BY symbol ) SELECT fs.* FROM filtered_step1 fs JOIN symbol_leverage_check slc ON fs.symbol = slc.symbol WHERE (slc.dir_count = 1) OR (slc.dir_count = 2 AND slc.long_leverage != slc.short_leverage);
SQL说明:
ranked_records给每个(symbol, direction)组的记录按杠杆降序排名,取排名1的就是每组最大杠杆的记录symbol_leverage_check统计每个symbol下的方向数量和对应杠杆值- 最后筛选出符合规则的记录
方案选择建议
- 如果数据量不大(万级以内),直接用Python处理更高效:不用额外搭建数据库,代码写好直接运行,调试也方便
- 如果数据量巨大,或者后续需要做更多维度的查询、统计,选MySQL更合适:数据库的索引和优化能大幅提升复杂查询的效率,而且可以复用数据做其他分析
内容的提问来源于stack exchange,提问作者btc4cash
相关产品推荐
相关产品推荐

