import numpy as np
import tushare as ts
import aiohttp
import asyncio
import time
codes = ['787819', '787317', '787317', '600320', '600191', '600191', '600967', '600765', '600238', '603650']
cvs_30 = []
start = time.time()
async def get_index(code):
all_data = ts.get_hist_data(code, start='2020-05-12', end='2020-12-28')
if all_data is None:
cv_30 = 0
# 加入相对应的列表
cvs_30.append(cv_30)
else:
data = all_data['close']
cv_30 = np.std(data.head(30)) / np.mean(data.head(30))
# 加入相对应的列表
cvs_30.append(cv_30 * 1000)
tasks = [asyncio.ensure_future(get_index(code)) for code in codes]
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.gather(*tasks))
end = time.time()
print(end - start)
python 同步代码改成异步的:各位大佬,下面是我写的读取tushare股票价格的大码,因为有多只股票,写成异步的,但是我写的代码执行后的效果还是同步的效果,请哪位大佬帮我修改下。
操,异步编程的类必须有_await_方法。现在大部分模块都不支持异步。还是用多线程或者多进程吧。
get_hist_data是阻塞模式?
异步IO的关键是非阻塞代码。
调用第三方库的方法用来读取他们数据库中的股票信息,应该是阻塞吧??
你代码缩进调一下,重发一下,我给你改一下
import numpy as np
import tushare as ts
import aiohttp
import asyncio
import time
codes = ['787819', '787317', '787317', '600320', '600191', '600191', '600967', '600765', '600238', '603650'] # 股票代码列表
cvs_30 = []
start = time.time()
async def get_index(code):
all_data = ts.get_hist_data(code, start='2020-05-12', end='2020-12-28')
if all_data is None:
cv_30 = 0
# 加入相对应的列表
cvs_30.append(cv_30)
else:
data = all_data['close']
cv_30 = np.std(data.head(30)) / np.mean(data.head(30))
# 加入相对应的列表
cvs_30.append(cv_30 * 1000)
tasks = [asyncio.ensure_future(get_index(code)) for code in codes]
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.gather(*tasks))
end = time.time()
print(end - start)
import numpy as np
import tushare as ts
import aiohttp
import asyncio
import time
codes = ['787819', '787317', '787317', '600320', '600191', '600191', '600967', '600765', '600238', '603650'] # 股票代码列表
cvs_30 = []
start = time.time()
async def get_index(code):
all_data = ts.get_hist_data(code, start='2020-05-12', end='2020-12-28')
if all_data is None:
cv_30 = 0
# 加入相对应的列表
cvs_30.append(cv_30)
else:
data = all_data['close']
cv_30 = np.std(data.head(30)) / np.mean(data.head(30))
# 加入相对应的列表
cvs_30.append(cv_30 * 1000)
tasks = []
for i in codes:
tasks.append(get_index(i))
loop = asyncio.new_event_loop()
loop.run_until_complete(asyncio.wait(tasks))
loop.close()
end = time.time()
print(end - start)
试试看
不行,你的代码是 1.7 秒左右 。 我用 for 循环是1.5秒
import numpy as np
import tushare as ts
import aiohttp
import asyncio
import time
codes = ['787819', '787317', '787317', '600320', '600191', '600191', '600967', '600765', '600238', '603650'] # 股票代码列表
cvs_30 = []
start = time.time()
for code in codes:
all_data = ts.get_hist_data(code, start='2020-05-12', end='2020-12-28')
if all_data is None:
cv_30 = 0
# 加入相对应的列表
cvs_30.append(cv_30)
else:
data = all_data['close']
cv_30 = np.std(data.head(30)) / np.mean(data.head(30))
# 加入相对应的列表
cvs_30.append(cv_30 * 1000)
end = time.time()
print(end - start)
结果:
C:\Users\elmaj\AppData\Local\Programs\Python\Python36\python.exe C:/Users/elmaj/PycharmProjects/SONG/test.py
1.5166161060333252
Process finished with exit code 0
你光看时间的吗? 你可以打印看看,在异步函数里加10s睡眠看看。
import numpy as np
import tushare as ts
import aiohttp
import asyncio
import time
codes = ['787819', '787317', '787317', '600320', '600191', '600191', '600967', '600765', '600238', '603650'] # 股票代码列表
cvs_30 = []
start = time.time()
async def get_index(code):
# 就是这里
await all_data = ts.get_hist_data(code, start='2020-05-12', end='2020-12-28')
if all_data is None:
cv_30 = 0
# 加入相对应的列表
cvs_30.append(cv_30)
else:
data = all_data['close']
cv_30 = np.std(data.head(30)) / np.mean(data.head(30))
# 加入相对应的列表
cvs_30.append(cv_30 * 1000)
tasks = [asyncio.ensure_future(get_index(code)) for code in codes]
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.gather(*tasks))
end = time.time()
print(end - start)
我理解的异步就是给IO操作前面添加 await 标志。
浏览你的代码,只有一处地方是非本地的IO操作,本地IO操作没有,剩下的全是本地的计算,所以在哪个IO操作前面加上await就行了
我运行你修改后的代码是以下的结果。还有我理解的异步就是:一个任务运行需要3秒,当相似的100各任务运行时需要的时间应该大大的小于300秒。
我有1000多支股票代码,多线程或者多进程可以吗?
多线程只占用一个进程,消耗很小,但是是一个人排队干活,效率慢
多进程就看你电脑的能力啦。去年我开50进程爬小说,瞬间占满48G内存,电脑当时就卡顿了。
我的主力电脑一般只开5-10进程。3.6GHz 4核心8线程,48G内存。
你上面的代码,10个不到2秒钟,1000个也就不到200秒。
如果你有很多电脑,可以用celery分布式异步任务。一台电脑发任务,几台电脑抢任务。