我有一长串数字(数十万项),我想创建一个大小相等的新列表,以找出连续重复数字的位置。新列表将具有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, []]
谢谢!
答案 0 :(得分:3)
如果组的长度大于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]
答案 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)
答案 2 :(得分:1)
这种情况更类似于run length encoding问题。考虑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
通过产生( value ,#repititions )的元组来压缩可迭代对象,例如:
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
安装。
答案 3 :(得分:0)
使用PANDAS shift
运算符创建向量移位1元素。比较原始。这将为您提供True / False值的向量,显示元素与上一个元素匹配的位置。在该列表下进行线性搜索,以在前面扩展一个元素:将[False,True]更改为[True,True]。转换为int
,您将获得指定的列表。