繁体   English   中英

如何在不使用groupby的情况下进行行程编码

[英]How to run-length encode without groupby

我已按如下顺序输入:

L = [5,5,7,7,7,7,9,10,12,14] 

我想计算每个数字出现的次数。 这给出了输出:

[2,4,1,1,1,1]

我不需要存储原始值。 我也不想使用groupby。 这是因为我将使用pypy运行我的代码,从而最好地加快简单循环的速度。

我可以使用以下方法来低效地做到这一点:

S = set(L)
[L.count(item) for item in S]

是否有一个简单的线性时间解决方案,也许只是一个for循环?

如果您有非常大的数据,请编写一些功能以提高效率。

L1 = [1, 1, 1, 1, 2, 2, 3, 4, 5, 6, 7, 8, 8, 8, 8, 8, 8, 8, 9]  
L2 = [1, 1, 1, 1, 2, 2, 3, 4, 5, 6, 7, 8, 8, 8, 8, 8, 8, 8, 8]

def countr(lst):
    res = []
    count = 1

    for i in range(len(lst) - 1):
        if lst[i] == lst[i + 1]:
            count += 1
        else:
            res.append(count)
            count = 1

    res.append(count)
    return res

countr(L1)
# [4, 2, 1, 1, 1, 1, 1, 7, 1]

countr(L2)
# [4, 2, 1, 1, 1, 1, 1, 8]

这是Counter创建的目的:

>>> from collections import Counter
>>> counts = Counter([5,5,7,7,7,7,9,10,12,14])
>>> [counts[i] for i in sorted(counts.keys())]
[2, 4, 1, 1, 1, 1]

另外,如果您要优化内存使用量,则可以使用以下函数进行迭代,甚至是从文件获取数字的生成器:

def run_lengths(lst):
    previous_val = None
    num_vals = 0 
    for i in lst:
        if previous_val is None:
            previous_val = i 
        if i == previous_val:
            num_vals += 1
            continue
        yield num_vals
        previous_val = i 
        num_vals = 1 
    if num_vals:
        yield num_vals

print(list(run_lengths([5,5,7,7,7,7,9,10,12,14])))  # Returns [1, 2, 4, 1, 1, 1]

def file_generator(file_path):
    with open(file_path, 'r') as f:
        for l in f:
            yield int(l.strip())

 print(list(run_lengths(file_generator('my/huge/file.dat'))))

暂无
暂无

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

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