如何在Pandas中按IP列分组计算唯一值并降低内存占用
低内存实现Pandas按IP聚合唯一值
我有一个包含ip、mac、hostname、os列的Pandas DataFrame,需要将其转换为ip列唯一,其余列列出对应IP的所有唯一值的新DataFrame。
输入DataFrame:
| ip | mac | hostname | os |
|---|---|---|---|
| 8.8.8.8 | 00:00:00:ff | dns.google.com | linux |
| 8.8.8.8 | 00:00:ff:ff | dns2.google.com | windows |
| 8.8.8.8 | 00:00:ff:ff | dns2.google.com | windows |
| 8.8.4.4 | 00:00:00:ff | dns.google.com | linux |
| 8.8.4.4 | 00:00:ff:ff | dns2.google.com | windows |
| 8.8.4.4 | 00:00:ff:ff | dns2.google.com | windows |
转换后DataFrame:
| ip | mac | hostname | os |
|---|---|---|---|
| 8.8.8.8 | 00:00:00:ff, 00:00:ff:ff | dns.google.com, dns2.google.com | linux, windows |
| 8.8.4.4 | 00:00:00:ff, 00:00:ff:ff | dns.google.com, dns2.google.com | linux, windows |
目前我用df.groupby('ip').agg(set)可以实现需求,但数据集较大时内存占用过高(500MB数据占用3-4GB内存),求低内存占用的替代方法。
输入数据创建代码:
import pandas as pd df = pd.DataFrame( { 'ip': ['8.8.8.8', '8.8.8.8', '8.8.8.8', '8.8.4.4', '8.8.4.4', '8.8.4.4'], 'mac': ['00:00:00:ff', '00:00:ff:ff', '00:00:ff:ff', '00:00:00:ff', '00:00:ff:ff', '00:00:ff:ff'], 'hostname': ['dns.google.com', 'dns2.google.com', 'dns2.google.com', 'dns.google.com', 'dns2.google.com', 'dns2.google.com'], 'os': ['linux', 'windows', 'windows', 'linux', 'windows', 'windows'], } )
解决方案
1. 先去重再聚合
原数据存在大量重复行,先对全表按所有列去重,能大幅减少后续分组处理的数据量,直接降低内存开销:
# 保留所有列的唯一行 df_unique = df.drop_duplicates() # 分组后拼接唯一值 result = df_unique.groupby('ip').agg(lambda x: ', '.join(x))
2. 用pd.unique替代set
pd.unique返回numpy数组,内存效率比Python原生set更高,避免了set对象的额外内存开销:
result = df.groupby('ip').agg(lambda x: ', '.join(pd.unique(x)))
3. 分块处理(超大数据集)
如果数据量远超内存,可分块读取处理,最后合并结果,避免一次性加载全部数据:
chunk_size = 100000 # 根据自身内存情况调整块大小 chunks = [] # 分块读取数据(假设数据来自CSV文件) for chunk in pd.read_csv('your_data.csv', chunksize=chunk_size): # 块内先去重再聚合 chunk_unique = chunk.drop_duplicates() chunk_agg = chunk_unique.groupby('ip').agg(lambda x: ', '.join(x)) chunks.append(chunk_agg) # 合并所有块的结果,再次聚合确保IP唯一且值无重复 result = pd.concat(chunks).groupby('ip').agg( lambda x: ', '.join(pd.unique(', '.join(x).split(', '))) )
4. 调用GroupBy的unique方法
直接使用Pandas GroupBy内置的unique方法,内部经过优化,内存效率更高:
result = df.groupby('ip').agg({ 'mac': lambda x: ', '.join(x.unique()), 'hostname': lambda x: ', '.join(x.unique()), 'os': lambda x: ', '.join(x.unique()) })
内容的提问来源于stack exchange,提问作者Peter
相关产品推荐
相关产品推荐

