我有一堆数据帧存储在字典(“df_dict”)中。每个数据帧有100行。对于每一行,我需要使用Reddit的当前数据添加列(“新评分”、“新评分”、“更新投票率”)。我正在使用PRAW访问RedditAPI
因为按顺序更新每一行需要很长时间,所以我尝试使用多线程来获取数据。因此,我使用一个包含100行的数据帧,为每个行启动一个线程,并为每个线程生成一个PRAW实例
不知何故,我的代码似乎可以工作并更新行,但它花费的时间太长了——太长了。按顺序更新没有区别。用我的“多线程”尝试更新一行几乎需要11.4秒。而如果我按顺序进行,则需要0.2秒。我做错了什么
这是我的密码。我尽可能多地删减,显然我修改了我的证件:
from threading import Thread, Lock
import praw
# Dataframes are stored in df_dict
mutex = Lock()
threads = []
class ReqThread (Thread):
def __init__(self, threadID, index, row):
Thread.__init__(self)
self.threadID = threadID
self.index = index
self.row = row
def run(self):
print("Starting %s" % self.threadID)
for row in self.row:
worker(index=self.index, row=self.row)
print("Exiting %s" % self.threadID)
def make_reddit():
return praw.Reddit(client_id=client_id, client_secret=client_secret, username=username, password=password, user_agent=user_agent)
def worker(index, row):
global df
print('Request-ID: %s' % row['id'])
reddit = make_reddit()
submission = reddit.submission(row['id'])
mutex.acquire()
df.at[index, 'new_score'] = submission.score
df.at[index, 'upvote_ratio'] = submission.upvote_ratio
df.at[index, 'new_num_comments'] = submission.num_comments
mutex.release()
for i in df_dict:
df = df_dict[i]
for index, row in df.iterrows():
t = ReqThread(threadID=index, index=index, row=row)
t.start()
threads.append(t)
for thread in threads:
thread.join()
df.to_csv('u_{i}.csv'.format(i=i))
编辑:再次计算我的“多线程”需要多少时间
您似乎遇到的是Python线程捕获
为什么这些“线程”较慢?
尽管看起来Python线程是而不是实际线程,但是_thread和threading模块使用操作系统线程,这些线程对于IO绑定的并发性很好,但对于CPU绑定的任务则不太好,这归结为Python和GIL(全局解释器锁)来保证所有线程安全。 因为你没有得到多核的好处,你只会得到平衡多个操作系统线程的开销
那么如何在Python中进行多核处理呢?
为了解决GIL问题,python使用子进程来基本平衡负载并使用多个核心,像multiprocessing这样的模块在内部使用subprocess模块,如果您创建了一个由4个工作进程组成的进程池并启动它们,您可以自己尝试一下,注意它是如何生成4个python进程的吗
需要注意的重要事项
相关问题 更多 >
编程相关推荐