Python 小白求助,如何快速循环百万条数据?
从 mongo 里读取用户数据
然后使用 jieba.analyse.extract_tags 进行提词
而且是对用户的几个属性进行提词,每个属性只取部分(权重较大的)
分词结果保存到 mongo 里
目前问题是:
1、单个用户提词速度感觉不慢,但是百万数据就要循环好久(目前本地测试 5 万数据都要 3 小时)
2、用户的几个属性分别提词,跟属性合并后提词,结果是否一样呢?
请大家指教一下 我该如何优化?
Python 小白求助,如何快速循环百万条数据?
看问题是出在数据库上还是 python 上。百万数据可能是从 db 拉取到本地时间过长。如果是 python 内循环处理时间过长。可以考虑多进程或者多线程处理。如果是 DB 上的问题。就用空间换时间吧。。
用for循环直接遍历百万条数据确实慢,核心是避免在Python层做低效循环。给你两个最实用的方案:
方案一:用NumPy向量化计算(首选) 如果你的数据能放进数组做批量计算,速度能提升几十到上百倍:
import numpy as np
# 假设要对百万个数字都加1
data = np.random.rand(1_000_000) # 百万随机数
result = data + 1 # 向量化操作,瞬间完成
方案二:用Pandas处理表格数据 如果是CSV这类结构化数据:
import pandas as pd
df = pd.read_csv('large_file.csv')
# 所有列乘以2,比循环快得多
df = df * 2
如果必须逐条处理,试试这些技巧:
- 用列表推导式代替
append():
# 慢
result = []
for x in data:
result.append(x*2)
# 快
result = [x*2 for x in data]
- 用
map()函数:
result = list(map(lambda x: x*2, data))
-
用PyPy解释器(纯Python代码能快2-10倍)
-
用内置
filter()/itertools处理过滤需求
关键点:百万条数据在内存里大概占8-80MB,现代计算机完全能hold住。瓶颈通常在于你的处理逻辑是不是向量化的。
一句话建议:能用NumPy/Pandas向量化就别用Python循环。
多进程?
多进程 or 任务队列?
合并后效率一样的,因为总的文本量并没有变
先把数据拉到内存里,然后用 pandas 操作
#1 应该是内循环时间太长了 我们一次取 5 万条数据,for 循环需要 2~3 小时
#2 有在考虑如何实现多进程,不过新手,还在学习呢
#3 我是想问几个属性合并后提词的结果跟每个属性提词的结果合并一样吗?
#4 好的,我去学学 pandas 如何使用
直接 multiprocessing.mapreduce 一句话的事
*.map
#6
#8
指定的是用 multiprocessing.Pool 类的 map 方法吗?
是的,这样也不用改代码
是也乎 ╮(╯▽╰)╭
直觉上…这业务不用在线就地计算的吧?
利用 mongoDB 的自动备份…将全数据…同步到另一主机…
用管理工具…将需要的数据定期 dump 到硬盘为 .csv .json 之类文本…
用 split 之类工具切开…
分别 丢给多个 python 进程…
仅将分词结果写回 mongoDB ?
这样不占用业务响应资源…
又最大化吞吐量…
同时…也免去了直拉 DB 的各种问题?
更重要的是…一切都是隔离可控的?
擦 忘记大佬叫啥了 活捉大神!!!!!
nb
感觉应该提词这比较慢,可以考虑用队列,mongo 读出数据丢到 redis 队列,然后多个消费者从队列消费提词。
对于第二条问题, 建议你所有属性合并后处理, 只要用分割符号(比如逗号)把属性连起来就行了, 这样分词效率要高很多.
看大神的回答,不止并发的问题,也许架构上也要重新想一想
import multiprocessing as pro
def work(string):
print (string)
if name == ‘main’:
p = pro.Pool()
with open(‘url.txt’, encoding=‘utf-8’) as url_list:
for url_per in url_list:
p.apply_async(work, args=(url_per,))
p.close()
p.join()
0-0 贴一个多进程的简单例子
缩进乱了。。。自己改一下 XD


