如何使用PRAW(Reddit)和多线程更新数据帧

2024-04-28 02:20:02 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一堆数据帧存储在字典(“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))

编辑:再次计算我的“多线程”需要多少时间


Tags: 数据inselfclientidsubmissiondffor
1条回答
网友
1楼 · 发布于 2024-04-28 02:20:02

您似乎遇到的是Python线程捕获

为什么这些“线程”较慢?
尽管看起来Python线程是而不是实际线程,但是_threadthreading模块使用操作系统线程,这些线程对于IO绑定的并发性很好,但对于CPU绑定的任务则不太好,这归结为Python和GIL(全局解释器锁)来保证所有线程安全。 因为你没有得到多核的好处,你只会得到平衡多个操作系统线程的开销

那么如何在Python中进行多核处理呢?
为了解决GIL问题,python使用子进程来基本平衡负载并使用多个核心,像multiprocessing这样的模块在内部使用subprocess模块,如果您创建了一个由4个工作进程组成的进程池并启动它们,您可以自己尝试一下,注意它是如何生成4个python进程的吗

需要注意的重要事项

  • python中的线程模块实际上通常是OS线程系统
  • GIL限制了python中的许多并行处理
  • IPC可能会更加困难,因为您没有获得跨进程自由传递变量的能力。有关更多信息,请参见MultiProcessing's Documentation

相关问题 更多 >