Skip to main content
 首页 » 编程设计

python之Pandas 内存管理问题

2025年05月04日24bluestorm

我遇到 Pandas 占用过多内存的问题。我有一个 5.5gb 的文件,其中有 2 列,我想简单地将所有唯一值保存在第一列中,如下所示:

Main File 
    Follower    Friend 
0   12          260009730 
1   12          17568791 
2   12          22512883 
3   12          15808761 
4   12          10135072 
5   12          988 
6   12          22424855 
7   13          9163182 
8   14          22990962 
9   15          7681662 
10  15          17289517 

到

Result File 
     User 
0    12 
1    13 
2    14 
3    15 

由于 RAM 限制,我将主文件分成 30 个部分导入,尝试从内存中清除数据帧,并且每次只附加结果文件。经过两次迭代(共 30 次),结果文件为 13.5mb。但它在第 6 次迭代后一直崩溃,我可以在我的进程管理中看到 python 占用了 4.5gb 的 RAM。我想调用垃圾收集器,但显然它不起作用,你们能帮帮我吗?我的代码如下:

i = 0 
userRelation = pd.DataFrame(columns=['User']) 
Location = 'file.txt' 
while i < 30: 
    userRelationHelp = pd.DataFrame(columns=['User']) 
    print(str(i)) 
    network = pd.read_csv(Location, sep="\t", header=None, encoding='Latin', low_memory=False, skiprows=(i * math.ceil(284884514/30)), nrows=(((i+1) * math.ceil(284884514/30))), names=['Follower', 'Friend']) 
 
    userRelationHelp['User'] = network['Follower'].unique() 
    userRelation = userRelation.append(userRelationHelp) 
    lst = [userRelationHelp, network] 
    del lst 
    gc.collect() 
    i += 1 

从我读到的 i += 1 之前的最后 3 行应该用于从内存中清除较大的文件。在每次迭代后,我可以看到我在循环开始时使用的 RAM 不断增加 ~200mb,并且在循环期间每次运行都会增加更多。

运行以上代码之前的基本 Python RAM 使用情况: 76mb

周期开始时 Python RAM 的近似使用情况

0: 300 
1: 800 
2: 1000 
3: 1300 

循环结束时的近似 Python RAM 使用量

0: 633 
1: 2000 
2: 2900 
3: 3700 

可以想象指出我在做什么或假设不正确吗?

请您参考如下方法:

@ypnos gave you a perfect description of how it should be done in Pandaic way.

这是我尝试编写的代码:

生成示例数据并将其写入 CSV:

fn = r'c:/temp/data.csv' 
 
pd.DataFrame(np.random.randint(1001, 9999, (10**5, 2))) \ 
  .to_csv(fn, sep='\t', index=False, header=None) 

仅处理 CSV 中我们需要的那些列:

chunksize=10**2  # you may want to use 10**7 as a chunk size 
reader = pd.read_csv(fn, sep='\t', usecols=[0], names=['Follower'],  
                     chunksize=chunksize, squeeze=True) 
 
df = pd.DataFrame(np.unique(np.concatenate([ser.unique() for ser in reader])), 
                  columns=['User']) 

结果:

In [62]: df 
Out[62]: 
      User 
0     1001 
1     1002 
2     1003 
3     1004 
4     1005 
5     1006 
6     1007 
7     1008 
8     1009 
9     1010 
...    ... 
8988  9989 
8989  9990 
8990  9991 
8991  9992 
8992  9993 
8993  9994 
8994  9995 
8995  9996 
8996  9997 
8997  9998 
 
[8998 rows x 1 columns]