【问题标题】:Efficiently counting items in large python lists有效地计算大型 python 列表中的项目
【发布时间】:2019-02-11 16:47:40
【问题描述】:

我有两个非常大的 python 列表,如下所示:

List A: [0,0,0,0,0,0,0,1,1,1,1,2,2,3,3,3,4.........]
List B: [0,0,0,0,0,0,2,2,2,2,3,3,4,4.........]

这些列表包含非常大的数字,但我指定了一个最大值,例如 100,然后我可以丢弃其余的。

现在我需要为每个值 (0,1,2..100) 计算比率:列表 A 中的出现次数 / 列表 B 中的出现次数。由于这个值并不总是可能的,所以我决定仅当每个列表中的值出现超过 5 次时才计算此值,并且如果此条件不成立,则合并先前值的出现,如果此条件,将为组合值提供相同的比率是正确的。 例如对于上面的列表,我想创建一个如下所示的系列:

0 : 7/6=1.166 
1 : 9/6 = 1.5
2 : 9/6 = 1.5
3 : 9/6 = 1.5
.
.
.
100 : some_number

【问题讨论】:

  • 7 = 列表 A 中的“0”计数,6 = 列表 B 中的“0”计数.. 7/6 = 1.166
  • 为什么是 1 1 : 9/6 = 1.5 而不是 1 : 4/0 = ...
  • 为什么超过 5 个?它应该只是超过 0
  • 如果您有 2 个列表,那么我认为没有办法至少查看列表中的每个元素一次。因此,包含 N 个元素的 2 个列表意味着您正在查看 2N 个运行时间。只需循环浏览您的列表。
  • 回答 Nick A:因为如前所述,只有在每个列表中出现超过 5 次的值时才应计算比率。 1 在列表 A 中仅出现 4 次,从不在列表 B 中,因此应与下一个值组合:2。即使将这 2 组合起来,它也不能满足要求,因此值 3 也被组合,然后出现1+2+3 是列表 A 中的 9 和列表 B 中的 6 - 所以计算的比率是 9/6 = 1.5。

标签: python algorithm pandas list


【解决方案1】:

您可以使用Counter 来计算出现次数,并使用takewhile 来满足您在100 停止的要求。

注意我如何使用nan,而不是丢弃不在列表b 中的值。

from collections import Counter
from itertools import takewhile

def get_ratios(a, b, max_=None, min_count=0):
    if max_ is not None:
        a = takewhile(lambda x: x <= max_, a)
        b = takewhile(lambda x: x <= max_, b)

    count_a, count_b = Counter(a), Counter(b)

    return {k: float('nan') if not count_b[k] else count_a[k] / count_b[k]
            for k in set(count_a) | set(count_b)
            if count_a[k] >= min_count <= count_b[k]}

示例

a = [1, 1, 1, 2, 3, 101]
b = [1, 1, 2, 2, 4, 101]

print(get_ratios(a, b, max_=100))

输出

{ 1: 1.5,
  2: 0.5,
  3: nan,
  4: 0.0 }

要忽略一些低于代表的值,您可以将min_count 设置为5,如您的问题中所述。

请注意,我没有使用前一个值的比率填充空槽。除非您有一个非常具体的用例需要它,否则我建议您不要这样做,因为这会将 实际 数据与 外推 数据混合在一起。没有找到时最好默认之前的值,但不要污染实际数据。

【讨论】:

    猜你喜欢
    • 2011-10-07
    • 2017-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-04
    • 2015-01-17
    • 1970-01-01
    相关资源
    最近更新 更多