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

如何在DataFrame中对IPv4与IPv6地址进行混合排序?

混合IPv4/IPv6地址的DataFrame排序解决方案

原始数据与需求

给定以下包含混合IPv4和IPv6地址的DataFrame:

import pandas as pd

df = pd.DataFrame(
    [
        {"group": "a", "ip_address": "10.3.110.12"},  # IPv4
        {"group": None, "ip_address": "10.3.110.127"},  # IPv4
        {"group": "c", "ip_address": "2607:f140:d000:135::7e9c"},  # IPv6
        {"group": "b", "ip_address": "10.3.110.90"},  # IPv4
    ]
)

需求:对ip_address列升序排序,要求IPv4在前,IPv6在后,且同类型IP内部按地址大小自然排序。

现有方法的问题

  • 方法1(ipaddress对象排序):IPv4Address和IPv6Address是不同类的对象,pandas无法跨类型比较,直接排序会触发TypeError。
  • 方法2(socket.inet_aton转换):仅支持IPv4,IPv6需要使用inet_pton,但两者返回的字节长度不同,无法统一排序。

可行解决方案

方案一:辅助列排序(兼容所有pandas版本)

通过添加类型标记和IP整数值两个辅助列,实现分层排序:

import ipaddress

# 定义IP处理函数,返回(类型标记, IP整数值)
def process_ip(ip_str):
    ip_obj = ipaddress.ip_address(ip_str)
    ip_type = 0 if isinstance(ip_obj, ipaddress.IPv4Address) else 1
    return (ip_type, int(ip_obj))

# 生成辅助列
df[['ip_type', 'ip_int']] = df['ip_address'].apply(lambda x: pd.Series(process_ip(x)))

# 按类型升序(IPv4在前)、IP整数值升序排序,最后删除辅助列
df_sorted = df.sort_values(by=['ip_type', 'ip_int'], ascending=True).drop(['ip_type', 'ip_int'], axis=1)

print(df_sorted)

输出结果:

group       ip_address
0      a     10.3.110.12
3      b      10.3.110.90
1   None    10.3.110.127
2      c  2607:f140:d000:135::7e9c

方案二:使用sort_values的key参数(pandas 1.1.0+)

利用sort_values的key参数直接生成排序键,无需辅助列,代码更简洁:

import ipaddress

# 定义排序键生成函数
def sort_key(ip_str):
    ip_obj = ipaddress.ip_address(ip_str)
    # 元组排序优先比较第一个元素(类型标记),再比较第二个元素(IP整数)
    return (0 if isinstance(ip_obj, ipaddress.IPv4Address) else 1, int(ip_obj))

# 直接按生成的键排序
df_sorted = df.sort_values(by='ip_address', key=lambda x: x.apply(sort_key))

print(df_sorted)

输出结果与方案一完全一致。

原理说明

  • 类型标记:用0标记IPv4,1标记IPv6,确保排序时IPv4始终排在IPv6前面。
  • IP整数值:将IPv4/IPv6地址转换为对应的整数(IPv4是32位整数,IPv6是128位大整数),利用整数的大小比较实现IP地址的自然排序。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 15:35:26