繁体   English   中英

Pandas pd.Series() 和 pd.DataFrame() 非常慢

[英]Pandas pd.Series() and pd.DataFrame() are very slow

我需要一些帮助来提高以下代码的性能。

        for object in dict_of_objects.values():
            test = pd.Series(object.properties)    #properties is a dict
            series_list.append(test)

        # List comprehension is not really faster than the loop since pd.Series() takes most time
        #series_list = [pd.Series(object.properties) for object in dict_of_objects.values()]

        # Also very slow
        df = pd.DataFrame(series_list)

在对代码进行一些计时后,我发现pd.Series(object.properties)pd.DataFrame(series_list)非常慢 - 两者都需要大约 9 秒才能完成,而 append 只需要 0.4 秒。 因此,列表理解并不是真正的改进,因为它也调用了 pd.Series(object.properties)。

您对如何提高此性能有一些建议吗?

最好的,朱尔兹

可以实现相同的结果,例如,如下所示:

properties_list = [o.properties for o in dict_of_objects.values()]
df = pd.DataFrame(properties_list).T

或者使用dict()的属性,这需要更少的操作:

properties_dict = {k: o.properties for k, o in dict_of_objects.items()}
df = pd.DataFrame.from_dict(properties_dict)

让我们看一些代码片段:

import numpy as np
import pandas as pd
from copy import deepcopy as cp

N_objects = 10
N_samples = 10000

class SimpleClass:
    def __init__(self,prop):
        self.properties = prop

dict_of_objects = {'obj{}'.format(i): 
                        SimpleClass({
                                        'alice' : np.random.rand(N_samples),
                                        'bob'   : np.random.rand(N_samples)
                                    }) for i in range(N_objects)}

def slow_update(dict_of_objects):
    series_list = []
    for obj in dict_of_objects.values():
        test = pd.Series(obj.properties)
        series_list.append(test)
    return pd.DataFrame(series_list)

def med_update(dict_of_objects):
    return pd.DataFrame([pd.Series(obj.properties) for obj in dict_of_objects.values()])

def fast_update(dict_of_objects):
    keys = iter(dict_of_objects.values()).__next__().properties.keys()
    return pd.DataFrame({k: [obj.properties[k] for obj in dict_of_objects.values()] for k in keys})

并有时间安排:

>>> %timeit slow_update(dict_of_objects)
2.88 ms ± 19.5 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
>>> %timeit med_update(dict_of_objects)
2.86 ms ± 23.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
>>> %timeit fast_update(dict_of_objects)
344 µs ± 17.6 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

快速更新执行以下操作:

  1. 使用__next__从迭代器中获取字段。
  2. 使用列表推导构造字段。
  3. 使用字典理解构造数据结构。

它比大多数方法快约 8 倍。

编辑:正如@koPytok 正确指出的那样,如果每个对象的properties属性具有不同的 keysfast_update将不起作用。 如果您选择为诸如 NoSQL 数据库抓取之类的东西实现此功能,请记住这一点——在 MongoDB 中,文档不需要共享相同的字段(此处交换文档为 ZA8CFDE6331BD59EB2AC96F8911C4B666 字段)。

享受!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM