繁体   English   中英

从给定列表创建新列表,以便新列表可以标记给定列表中的连续重复

[英]Create a new list from a given list such that the new list can flag consecutive repetitions in the given list

我有一长串数字(数十万项),我想创建一个大小相等的新列表,以找出连续重复数字的位置。 新列表将具有0和1值,因此对于连续的重复索引,新列表将具有1,其余索引将具有0值。

如果在pandas列中有一些内容也可能会有所帮助。

给定样本列表和结果数组。 列表也可以具有浮点值。

given_array = [1, 2, 3, 5, 5, 5, 5, 0, -2, -4, -6, -8, 9, 9, 9]

result_array = [0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1]

我在下面给出了我的代码的一个小示例。

import itertools    

def list_from_count(list_item):
    """
    Function takes an iterator and based on the length of the item
    returns 1 if length is 1 or list of 0 for length greater than 1
    """
    if len(list(list_item[1])) == 1:
        return 1
    else:
        return [0] * len(list(list_item[1]))

r0 = list(range(1,4))
r1 = [5]*4
r2 = list(range(0,-10,-2))
r3 = [9]*3
r = r0 + r1 + r2 + r3


gri = itertools.groupby(r)
res = list(map(list_from_count,gri))

print ("Result",'\n',res)

结果

[1, 1, 1, [], 1, 1, 1, 1, 1, []]

提前致谢!

如果组的长度大于1,则可以使用itertools.groupby并重复输出1 s:

from itertools import groupby

result_array = []
for _, g in groupby(given_array):
    size = sum(1 for i in g)
    if size == 1:
        result_array.append(0)
    else:
        result_array.extend([1] * size)

或具有列表理解:

result_array = [i for _, g in groupby(given_array) for s in (sum(1 for i in g),) for i in ([0] if s == 1 else [1] * s)]

result_array变为:

[0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1]

您使用len(list(list_item[1]))两次。 第一次使用它时,它将处理迭代器中的所有项目。 当您第二次调用它时,迭代器已全部用尽,因此返回0 ,这就是为什么您会得到一个零元素列表的原因。

您需要在第一次将长度保存在变量中:

def list_from_count(list_item):
    l = len(list(list_item[1]))
    if l == 1:
        return [0]
    else:
        return [1] * l

您还需要从该函数一致地返回一个列表,然后才能将所有结果连接起来,这样就不会混用数字和子列表。

res = []
for el in gri:
    res += list_from_count(el)
print(res)

这种情况更类似于游程长度编码问题。 考虑more_itertools.run_length

特定

import more_itertools as mit


iterable = [1, 2, 3, 5, 5, 5, 5, 0, -2, -3, -6, -8, 9, 9, 9]

result = [[0] if n == 1 else [1] * n for _, n in mit.run_length.encode(iterable)]
result
# [[0], [0], [0], [1, 1, 1, 1], [0], [0], [0], [0], [0], [1, 1, 1]]

现在只需将子列表(无论您希望如何)展平到一个列表中:

list(mit.flatten(result))
# [0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1]

细节

mit.run_length.encode通过产生( valuerepititions# )元组来压缩可迭代对象 ,例如:

list(mit.run_length.encode("abaabbba"))
# [('a', 1), ('b', 1), ('a', 2), ('b', 3), ('a', 1)]

我们的理解忽略该值,使用重复n并创建[0][1] * n子列表。

注意: more_itertools是第三方软件包。 通过> pip install more_itertools

使用PANDAS shift运算符创建向量移位1元素。 比较原始。 这将为您提供True / False值的向量,显示元素与上一个元素匹配的位置。 在该列表下进行线性搜索,以在前面扩展一个元素:将[False,True]更改为[True,True]。 转换为int ,您便拥有了指定的列表。

暂无
暂无

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

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