pandas 如何在一个 Dataframe 中对IPv4和IPv6地址进行排序?

omvjsjqw  于 2023-02-27  发布在  其他
关注(0)|答案(1)|浏览(310)

下面是我的数据框:

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
    ]
)

我想在一个 Dataframe 列中按升序对Ipv4和Ipv6 IP地址进行排序。
我尝试了两种方法,但都失败了。

方法1-将df ip_address列值转换为python ip_address对象并尝试排序

它对一种IP地址(ip4或ip6)工作正常,但不能同时使用。

import ipaddress

# Converting the  ip_address string value to ip_address object
df['ip_add'] = df['ip_address'].apply(lambda x: ipaddress.ip_address(x))
    
# sort df in asc and desc
df = df.sort_values(by=['ip_add'], ascending=True) # asc and desc
         
df = df.drop(["ip_add"], axis=1)

方法2-将df ip_address列值转换为socket. inet_aton值并使用argsort进行排序

它对一种IP地址(即ip4)工作得很好,但对单独的ip6就不行了。

df = df.iloc[np.argsort(list(map(socket.inet_aton, df['ip_address'])))]

预期结果

Dataframe 按升序排序(最小单元先到,即Ivp4先到,然后是Ipv6值)

wtlkbnrh

wtlkbnrh1#

下面是第一种方法的一种实现方式,使用Python标准库的ipaddress模块和isinstance内置函数,以及Pandas concatenate方法:

# Convert the  ip_address string value to ip_address object
df["ip_address"] = df["ip_address"].apply(lambda x: ipaddress.ip_address(x))

# Split dataframe between IPv4 and IPv6 values, sort separately 
# and concatenate them back together
df = pd.concat(
    [
        df[df["ip_address"].apply(lambda x: isinstance(x, ip_add))].sort_values(
            by="ip_address"
        )
        for ip_add in (ipaddress.IPv4Address, ipaddress.IPv6Address)
    ],
    ignore_index=True,
)

然后:

print(df)

相关问题