我想在Ruby代码中使用一些有趣的用例,并将它们转换为Python。我认为我们可以在任何lib中使用,我主要使用pandas和numpy。
例如,假设您有一个定时事件数组,这些事件有一个时间戳和另一个属性(一个对象或一个元组)。
我想要一个组列表/数组,其中这些组是“连续的”事件,其宽限期为g
个单位(在这种情况下为时间单位)。
在我的Ruby代码中,我使用类似这样的内容:
grouped_events = events.chunk_while do |previous_event, next_event|
next_event.timestamp <= previous_event.timestamp + grace_period
end
由于我不仅在定时事件中使用了我可以排序的东西(所以它们在某种程度上是可比的),所以我问:有一种通用的方法,或者是已知的lib可以做到这一点?
答案 0 :(得分:2)
Python没有等效功能。您必须自己编写。
这是我的实现,使用iterator和yield
statement:
def chunk_while(iterable, predicate):
itr = iter(iterable)
try:
prev_value = next(itr)
except StopIteration:
# if the iterable is empty, yield nothing
return
chunk = [prev_value]
for value in itr:
# if the predicate returns False, start a new chunk
if not predicate(prev_value, value):
yield chunk
chunk = []
chunk.append(value)
prev_value = value
# don't forget to yield the final chunk
if chunk:
yield chunk
可以像这样使用:
>>> list(chunk_while([1, 3, 2, 5, 5], lambda prev, next_: next_ <= prev + 2))
[[1, 3, 2], [5, 5]]
答案 1 :(得分:1)
我不知道有一个现成的解决方案,但是从头开始编写一个解决方案并不难。遍历序列的元素,根据您的条件测试每对项目,然后选择是将其添加到现有组中还是创建新组。
import collections
def pairs(seq):
"""yields (previous, current) pairs from the given iterable."""
no_item = object()
previous = no_item
for item in seq:
if previous is not no_item:
yield (previous, item)
previous = item
def chunk_contiguous(seq, criteria):
cur_group = []
for previous, current in pairs(seq):
if criteria(previous, current):
cur_group.append(current)
else:
yield cur_group
cur_group = [current]
if cur_group:
yield cur_group
Event = collections.namedtuple("Event", ["name", "timestamp"])
events = [
Event("foo", 0),
Event("bar", 1),
Event("baz", 10),
Event("qux", 12),
Event("Larry", 17),
Event("Curly", 21),
Event("Moe", 25),
]
g = 4
for group in chunk_contiguous(events, lambda previous, current: current.timestamp <= previous.timestamp + g):
print(group)
结果:
[Event(name='bar', timestamp=1)]
[Event(name='baz', timestamp=10), Event(name='qux', timestamp=12)]
[Event(name='Larry', timestamp=17), Event(name='Curly', timestamp=21), Event(name='Moe', timestamp=25)]