使用python的pandas模块时,查找和修改dataFrame中的值速度非常慢,请问是什么原因,有什么好办法解决吗?

发布于 2022-09-02 20:33:43 字数 1276 浏览 12 评论 0

最近在用pandas做一个机器学习的项目,训练集大概2G。我用的dataFrame来操作数据,对训练集做了一次groupby和mean的操作,速度还挺快的,但把得到的结果赋值给用户参数(也是一个dataframe表)的时候,速度缺特别慢,请问这是什么原因呢?
训练集大概有7000多万行,做groupby和mean操作大概十几分钟也就完成了,但赋值操作缺超级慢,每秒钟大概只能赋值50条左右,差距太大了。其中赋值语句大概是这样操作的:
dataframeA.loc[user,'']=dataframeB.loc[user,'']。两张dataFrame表都很大,都是百万级的,不知道是不是和量级较大有关,但千万级的训练集做groupby也没什么压力啊,而且这个机器学习项目,会经常使用和修改表中的参数,如果都这么慢的话,可能就无法正常使用了,哪位大神有什么好的解释或者建议吗?非常感谢了。部分代码如下,有什么细节没有说清楚的话可以问我,我再详细解释下。

def get_average_rating(self):
        self.u = log_train['Result'].mean()
        print 'u is ',self.u
        i,j = 0,0
        user_mean_rate = log_train.groupby('UserId').agg({'Result':np.mean})
        item_mean_rate = log_train.groupby('ItemId').agg({'Result':np.mean})

        #计算bias
        print 'calc bias start'
        start_time = time.time()
        for user in train_users:
            i += 1
            if i%2000==0:
                print '2000 used time',time.time()-start_time
                start_time = time.time()
            self.user_params.loc[user,'bias'] = user_mean_rate.loc[user,'Result']-self.u
        for item in train_items:
            self.item_params.loc[item,'bias'] = item_mean_rate.loc[item,'Result']-self.u

        print 'bias total used time',time.time()-start_time

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

折戟 2022-09-09 20:33:43

pandas 存在 df.iterrows() 的generator 来循环DataFrame 的 row, 这样的效率是最高的。

详细可以看文档说明:
http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.iterrows.html

一个人的旅程 2022-09-09 20:33:43

没做过这么大的数量级,但我的经验是,df最好不要逐条操作,基本都慢,整列操作快很多
1.增 (append)
最好在一个空的df写好全部新增值,然后merge
但有时直接append也是难免的
2.删
直接用del语句比较快
3.改
也是采用合并的思路,覆盖原值

把梦留给海 2022-09-09 20:33:43

我感觉不是赋值慢
self.user_params.loc[user,'bias']这条等于是一级index里再取二级index,应该会很慢
能否把item和user分成两个dataframe呢?

吃兔兔 2022-09-09 20:33:43

loc是最慢的。尽量用ix代替。最好能使用iterrows 构造循环。

瑾夏年华 2022-09-09 20:33:43

赋值的话用iterrows不行,因为文档里写了ou should never modify something you are iterating over.

静赏你的温柔 2022-09-09 20:33:43

s = log_train.groupby('UserId')['Result'].transform(mean),用这个返回和self.u 行数相等的列,直接使用 s-u 得到每个user 对应的均值差,然后直接根据user赋值给self.user_params['bias']。 在做计算时候 尽量使用np.array 直接计算,避免 for 循环。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文