2015-07-10 98 views
3

我想读和处理大量的CSV文件(data_file),其具有下面的2柱结构:大熊猫:处理一个数据帧具有大量串

id params 
1 '14':'blah blah','25':'more cool stuff' 
2 '157':'yes, more stuff','15':'and even more' 
3 '14':'blah blah','25':'more cool stuff' 
4 '15':'different here' 
5 '157':'yes, more stuff','15':'and even more' 
6 '100':'exhausted' 

该文件包含30.000.000线(磁盘上5 Gb)。 (实际的字符串以UTF-8编码;为了简单起见,我在这里给出了他们的ASCII码)。请注意,第二列中的一些值会重复。

我阅读此使用pandas.read_csv()

df = pandas.read_csv(open(data_file, 'rb'), delimiter='\t', 
     usecols=['id', 'params'],dtype={'id':'u4', 'params':'str'}) 

一旦文件被读取时,数据帧df使用的RAM 1.2 GB。

到目前为止这么好。

现在来处理部分。我想有这个格式,params字符串列:

blah blah||more cool stuff 
yes, more stuff||and even more 
blah blah||more cool stuff 
different here 
yes, more stuff||and even more 
exhausted 

我写道:

def clean_keywords(x): 
    return "||".join(x.split("'")[1:][::2]) 

df['params'] = df['params'].map(clean_keywords) 

此代码工作在这个意义上它给出正确的结果。但是:

  1. 执行map操作时使用的RAM超过6.8 Gb。
  2. 计算完成后,尽管在params列中计算的字符串比读取的字符串短,但使用了5.5 Gb的RAM df(在gc.collect()之后)。

有人可以解释这一点,并提出一种使用熊猫来执行上述操作的替代方法(我使用python 3.4,pandas 0.16.2,win64)?

+0

你的代码产生这样的:'缺货[69]: ID PARAMS 0 1 14 ||等等等等|| || 25更凉爽的东西 1 2 157 ||是,更多的东西|| || 15乃至str.split(“'”)。str [1:]。str [:: 2] .str.join('||')' – EdChum

+0

@EdChum,我简化了我实际编写的原始代码。也许我犯了一个错误?我没有得到你想告诉我的。你的代码更有效率?我刚刚试过你的代码:RAM超过7 GB。 –

+0

这也许因为这是矢量化'str'方法也许值得尝试修改代码以使用类似于我建议的代码,这可能不是解决你的记忆问题,虽然 – EdChum

回答

2

回答我自己的问题。

事实证明,pandas.read_csv()是聪明的。读取文件时,字符串是唯一的。但是,当这些字符串被处理并存储在列中时,它们不再是唯一的。因此RAM使用率增加。为了避免这种情况,必须手动维护唯一性。我这样做:

unique_strings = {} 

def clean_keywords(x): 
    s = "||".join(x.split("'")[1:][::2]) 
    return unique_strings.setdefault(s, s) 

df['params'] = df['params'].map(clean_keywords) 

有了这种解决方案,RAM最大。正如预期的那样,在读取数据(1.2 Gb)后,在最初的RAM使用情况下,使用量仅为2.8 Gb,并略有下降。

+0

这似乎是一个有用的技术知道。 –