含空值的Python多维数组按datetime子数组排序问题
解决多维数组按Datetime子数组同步排序的问题
我来帮你搞定这个排序问题,先理清楚核心需求:根据第一个子数组(全是datetime对象)的排序顺序,同步调整其他子数组的元素位置,而不是对每个子数组单独排序。之前的sorted代码报错,是因为你错误地用了每个子数组的第一个元素作为排序键,导致None和datetime对象无法比较,这完全偏离了你的实际需求。
现有Pandas方案的优缺点
你用Pandas的方案确实能解决问题,优点是代码简洁,Pandas对行列操作的封装很成熟;但缺点也很明显:
- 引入了第三方依赖,如果是小型脚本或者环境受限的场景,有点大材小用
- 可能会自动转换datetime为timestamp(取决于具体操作),破坏原数据类型
纯Python无依赖的最优方案
其实用纯Python就能高效解决这个问题,核心思路是先获取datetime子数组的排序索引,再用这个索引同步重排所有子数组,步骤如下:
步骤1:生成排序索引
先对第一个子数组的元素和它们的原始索引配对,按datetime从小到大排序后,提取出排序后的索引顺序:
import datetime import psycopg2.tz # 你的原数组 ar = [ [datetime.datetime(2018, 4, 11, 4, 0, 30,tzinfo=psycopg2.tz.FixedOffsetTimezone(offset=0, name=None)), datetime.datetime(2018, 4, 11, 4, 0, 29, tzinfo=psycopg2.tz.FixedOffsetTimezone(offset=0, name=None)), datetime.datetime(2018, 4, 11, 4, 0, 28, tzinfo=psycopg2.tz.FixedOffsetTimezone(offset=0, name=None))], [None,2,1], [None,2,1], [None,2,1] ] # 获取第一个子数组的排序索引:按datetime升序排列,得到原始位置的索引列表 sorted_indices = sorted(range(len(ar[0])), key=lambda i: ar[0][i])
步骤2:同步重排所有子数组
遍历每个子数组,按照刚才生成的索引顺序重新取元素:
# 对每个子数组应用排序索引,得到最终排序后的数组 sorted_ar = [ [sub_arr[i] for i in sorted_indices] for sub_arr in ar ]
运行后得到的sorted_ar就是你想要的结果:
[ [datetime.datetime(2018, 4, 11, 4, 0, 28,tzinfo=psycopg2.tz.FixedOffsetTimezone(offset=0, name=None)), datetime.datetime(2018, 4, 11, 4, 0, 29, tzinfo=psycopg2.tz.FixedOffsetTimezone(offset=0, name=None)), datetime.datetime(2018, 4, 11, 4, 0, 30, tzinfo=psycopg2.tz.FixedOffsetTimezone(offset=0, name=None))], [1,2,None], [1,2,None], [1,2,None] ]
扩展:处理datetime子数组含None的情况
如果你的datetime子数组里也有None,可以在生成索引时自定义None的排序位置(比如把None放在最后):
# 把None排在最后,然后按datetime升序 sorted_indices = sorted(range(len(ar[0])), key=lambda i: (ar[0][i] is None, ar[0][i]))
总结
- 如果你的项目已经依赖Pandas,原方案可以继续用,但要注意数据类型的转换问题
- 追求轻量、无依赖或者需要更灵活的排序逻辑时,纯Python的索引排序方案是最优选择,效率高且完全保留原数据类型
内容的提问来源于stack exchange,提问作者Phillip Stack
相关产品推荐
相关产品推荐

