我有一个非常大的 CSV 文件(数十千兆),其中包含带有以下列的网络日志:user_id
, time_stamp
, category_clicked
。我必须构建一个记分器来识别用户喜欢和不喜欢的类别。请注意,我有超过 1000 万用户。
我首先把它切成块并存放在一个HDFStore
named input.h5
然后我用groupby
on user_id
下列的杰夫的方式.
这是我的数据:大约 2 亿行,1000 万个唯一的 user_ids。
user id | timestamp | category_clicked
20140512081646222000004-927168801|20140722|7
20140512081714121000004-383009763|20140727|4
201405011348508050000041009490586|20140728|1
20140512081646222000004-927168801|20140724|1
20140501135024818000004-1623130763|20140728|3
这是我的 pandas.show_version():
INSTALLED VERSIONS
------------------
commit: None
python: 2.7.6.final.0
python-bits: 64
OS: Windows
OS-release: 8
machine: AMD64
processor: AMD64 Family 21 Model 2 Stepping 0, AuthenticAMD
byteorder: little
LC_ALL: None
LANG: fr_FR
pandas: 0.13.1
Cython: 0.20.1
numpy: 1.8.1
scipy: 0.13.3
statsmodels: 0.5.0
IPython: 2.0.0
sphinx: 1.2.2
patsy: 0.2.1
scikits.timeseries: None
dateutil: 2.2
pytz: 2013.9
bottleneck: None
tables: 3.1.1
numexpr: 2.3.1
matplotlib: 1.3.1
openpyxl: None
xlrd: 0.9.3
xlwt: 0.7.5
xlsxwriter: None
sqlalchemy: 0.9.4
lxml: None
bs4: None
html5lib: None
bq: None
apiclient: None
这是我想要的输出:
对于每个 user_id,一个列表[0.1,0.45,0.89,1.45,5.12,0.,0.,0.45,0.12,2.36,7.8]
表示用户对每个类别的分数和全局分数。我无法告诉您有关分数的更多信息,但它需要计算所有时间戳和category_clicked。你不能事后总结或者类似的事情。
这是我的代码:
clean_input_reader = read_csv(work_path + '/input/input.csv', chunksize=500000)
with get_store(work_path+'/input/input.h5') as store:
for chunk in clean_input_reader:
store.append('clean_input', chunk,
data_columns=['user_id','timestamp','category_clicked'],
min_itemsize=15)
groups = store.select_column('clean_input','user_id').unique()
for user in groups:
group_user = store.select('clean_input',where=['user_id==%s' %user])
<<<<TREATMENT returns a list user_cat_score>>>>
store.append(user, Series(user_cat_score))
我的问题如下:在我看来,这一行:group_user=store.select('clean_input',where=['user_id==%s' %user])
时间复杂度太高了,因为我真的有很多组,而且我确信在例程中存在很多冗余排序store.select
如果我应用它一千万次。
为了给你一个估计,我采取250 秒处理 1000 个按键使用这种技术,而不是仅仅1 second在通常的情况下groupby
读取全内存 CSV 文件read_csv
没有分块。
**********更新***********
应用 Jeff 的哈希方法后,我可以在 1 秒内处理 1000 个键(与完全内存方法的时间相同),并且绝对减少了 RAM 使用量。当然,我以前没有经历过的唯一时间损失是我进行分块、保存 100 个哈希组以及从存储中的哈希组中获取真实组所花费的时间。但这个操作不会超过几分钟。