【问题标题】:improve performance fetching data from mongodb提高从 mongodb 获取数据的性能
【发布时间】:2017-05-01 04:42:01
【问题描述】:
earnings = self.collection.find({}) #return 60k documents
----
data_dic = {'score': [], "reading_time": [] }
for earning in earnings:
    data_dic['reading_time'].append(earning["reading_time"])
    data_dic['score'].append(earning["score"])
----
df = pd.DataFrame()
df['reading_time'] = data_dic["reading_time"]
df['score'] = data_dic["score"]

--- 之间的代码需要 4 秒才能完成。如何改进此功能?

【问题讨论】:

  • 一种可能性是预先分配 data_dic 中的每个列表,然后简单地更改特定索引处的元素,而不是不断地附加到列表中。此外,如果您有多个内核可供使用,您可以引入多线程。

标签: python mongodb pandas pymongo


【解决方案1】:

时间由这几部分组成:mongodb查询时间、数据传输时间、网络往返时间、python列表操作。您可以对它们中的每一个进行优化。

一是减少传输的数据量。由于您只需要reading_timescore,因此您只能获取它们。如果您的平均文档大小很大,这种方法非常有效。

earnings = self.collection.find({}, {'reading_time': True, 'score': True})

第二。 Mongo 批量传输有限数量的数据。数据最多包含 60k 行,需要多次传输数据。您可以调整cursor.batchSize 以减少往返次数。

第三,如果可以的话,增加网络带宽。

第四。您可以利用numpy array 加速。它是一种类 C 的数组数据结构,比 python 列表更快。预分配固定长度数组并按索引赋值。这样可以避免调用list.append时进行内部调整。

count = earnings.count()
score = np.empty((count,), dtype=float)
reading_time = np.empty((count,), dtype='datetime64[us]')
for i, earning in enumerate(earnings):
    score[i] = earning["score"]
    reading_time[i] = earning["reading_time"]

df = pd.DataFrame()
df['reading_time'] = reading_time
df['score'] = score

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-15
    • 1970-01-01
    相关资源
    最近更新 更多