【问题标题】:Rolling median for a large dataset - python大型数据集的滚动中位数 - python
【发布时间】:2015-07-08 18:11:39
【问题描述】:

我有一个包含 200K 行的大文件,我需要通过计算每行中不同的单词来找出滚动中位数。

我使用 numpy 计算中位数如下

   a = np.array([])
   np.insert(a, 0, len(unique_word_list_by_line))
   median = np.median(a)

我觉得这效率不高,因为每次我插入一个元素时 numpy 都会创建一个新数组。有没有办法将元素插入到 numpy 数组中?

谢谢

【问题讨论】:

  • “numpy 比其他统计软件包更好......”这个问题并不适合 SO。太模糊了:有太多的包可以比较。听起来您正在寻找的是帮助优化您的代码。你所拥有的非常未经优化。考虑重写您的问题,就如何优化代码征求建议。特别是,您对 np.insert 的使用非常慢,因为 numpy 每次迭代都必须创建一个新数组。
  • 感谢您的 cmets,我已经更新了问题
  • 您的示例代码中是否缺少for 循环?

标签: python numpy pandas scipy median


【解决方案1】:

动态填充 numpy 数组从来都不是好事,它涉及调整大小和复制。

滚动中位数并不像看起来那么简单。 This blog article 谈论不同的实现,例如Skip list

编辑:您似乎使用熊猫。在 pandas 中,使用跳过列表和跳过 NaN 的实现已经实现。看看here

也可以在 here 找到在纯 python 中实现它的秘诀。

【讨论】:

  • 谢谢,但是每次我们向列表中添加新元素并调用 np.median(list) 时,它不会创建 numpy 数组吗?
  • 我不明白,每次读取文件中的一行需要计算中位数吗?
  • 是的,因为它的滚动中位数。我需要逐行阅读,计算每行唯一单词并找到滚动中位数。例如:第 1 行 - 单词 - 5,第 2 行 - 单词 7,第 3 行 - 单词 10 中位数为 5, (5+7)/2, 7
【解决方案2】:

我建议这样做。假设您已将文本文件加载到 file,您可以将列表 a 创建为:

a = []
for line in file:
    a.append(num_unique_words(line))

我假设您有一个函数 num_unique_words 来计算字符串中唯一单词的数量。

现在将其转换为数组:

a = np.array(a)

现在将views 上的np.median 调用到数组中(注意视图是由slicing 数组创建的:

median = np.empty_like(a)
for idx in xrange(len(a)):
    median[idx] = np.median(a[:idx])

【讨论】:

  • 当然,numpy 每次调用np.median 时都会执行整个排序操作,而不是简单地将最近添加的值插入到排序中。出于这个原因,@Kikohs 的答案提供了指向肯定会更快的方法的链接。
  • 不错。如果文件的全部内容(唯一字数)可以加载到内存中,则此解决方案有效。但是如何修改这个解决方案以适应无法放入内存的大数据集?
  • 200000 个条目并不多;它只有几兆字节左右。对?我错过了什么吗?
  • 你是对的@farenorth,我只是想看看这种方法是否可以扩展到非常大的数据集
  • 在我看来,如果您的文件那么长,那么您还有其他问题。特别是,您需要实现@Kikohs 建议的那种快速“运行中位数”。
猜你喜欢
  • 1970-01-01
  • 2020-10-09
  • 2017-12-05
  • 2011-11-01
  • 1970-01-01
  • 2014-09-26
  • 1970-01-01
  • 2019-02-11
  • 2020-05-16
相关资源
最近更新 更多