首页 > 解决方案 > Python:运行 Slooooow 的程序

问题描述

我的 Pandas 数据分析运行速度非常慢时遇到问题,想知道是否有人可以提供帮助。

我有 2 个数据帧,我正在尝试比较一个帧中的 IP 地址是否是另一帧中网络的一部分:

我正在向 AssetFrame 添加额外的 7 列,以便在匹配后获取新值。

for index, row in AssetFrame.iterrows():
    IPstore = AssetFrame.loc[index, 'ipv4s'].split(',')
    
    for index, row in VFFrame.iterrows():
        net = ipaddress.IPv4Network(VFFrame.loc[index, 'CIDR'])
    
        for i in range(len(IPstore)):
            IPstore[i] = IPstore[i].strip()
            IP = ipaddress.IPv4Address(IPstore[i])
        
            if IP in net:
                row = [IP, net]       # Used to check list of matches to export as CSV,
                TheList.append(row)   # to check my assumption below is correct.

                # All IPs will be in the same network 'CIDR' or there will be no match
                # The columns have already been added to the AssetFrame ready to take the new values
                AssetFrame.loc[index, 'comment'] = VFFrame.loc[index, 'comment']
                AssetFrame.loc[index, 'country'] = VFFrame.loc[index, 'country']
                AssetFrame.loc[index, 'city'] = VFFrame.loc[index, 'city']
                AssetFrame.loc[index, 'site-name'] = VFFrame.loc[index, 'site-name']
                AssetFrame.loc[index, 'site-id'] = VFFrame.loc[index, 'site-id']
                AssetFrame.loc[index, 'vf-device'] = VFFrame.loc[index, 'vf-device']
                AssetFrame.loc[index, 'vlan'] = VFFrame.loc[index, 'vlan']



AssetFrame:
    id            ipv4s             fqdn
0   b564a4        192.168.20.4      too.many@cats121.com
1   e454a4        192.168.20.74     too.many@dogs231.com
2   a454a4        192.168.20.84     too.many@worms456.com

VFFrame:
    subnet          mask                CIDR                Comment         vlan
0   192.168.20.0    255.255.255.224     192.168.20.0/26     Blah Blah       101
1   192.168.20.64   255.255.255.240     192.168.20.64/28    Ditto Blah      201

Result Should be:
AssetFrame:
    id        ipv4s             fqdn                    Comment         vlan
0   b564a4    192.168.20.4      too.many@cats121.com    Blah Blah       101
1   e454a4    192.168.20.74     too.many@dogs231.com    Ditto Blah      201
2   a454a4    192.168.20.84     too.many@Worms456.com   No Match        No Match

数据帧和想要的输出示例:

标签: pythonpython-3.xpandasperformancelarge-data-volumes

解决方案


“分而治之”是你的朋友。首先,我们有 O(n³) 复杂度,这没什么大不了的。在这些情况下,第一步是了解时间浪费在哪里,我可以猜测 .loc 是瓶颈。但为了清晰的分析,我建议使用执行工具。我编写了perf_tool可以指导您找到解决方案:

一些热门歌曲

  • 当您可以在矢量模式下进行时,内部循环会进行标量赋值。AssetFrame.loc非常昂贵且调用次数过多。

  • 中间循环对每条记录再次进行详细说明,这可以使用掩码在矢量模式下完成

  • Top Loop 再次迭代每一行。

  • 在 DataFrame 之间进行一次合并操作可能会删除 Top 和 Middle 循环。


推荐阅读