Ability to add data instead of having to pass generators
sytelus opened this issue · 5 comments
It would be very convenient if there was a method such as append()
to add series in arbitrary manner instead of having to use generators. In many cases, converting existing code to form generators is time consuming and can become complex task in multithreaded environment.
Hi @sytelus, thanks for opening the issue.
I just want to be sure I've understood correctly - do you mean that you'd like to append additional iterable objects to an already existing rolling object?
For example, if a rolling sum object r
is created over some iterable (e.g. a list):
>>> import rolling
>>> numbers = [1, 5, 2, 0, 3]
>>> r = rolling.Sum(numbers, 3)
then later we can use append()
to add more values from another iterable for the rolling window to move across...
>>> more_numbers = (3, 1, 4, 1, 5)
>>> r.append(more_numbers)
>>> list(r)
[8, 7, 5, 6, 7, 8, 6, 10] # rolling sum of 3 values over [1, 5, 2, 0, 3, 3, 1, 4, 1, 5]
If so that seems very doable, though please let me know if I've misunderstood your suggestion!
Thanks for building this nifty, minimal library! Old thread, but I second that a feature along these lines would be immensely helpful. Perhaps it is worth exposing a push
command as well? My desired use case is to:
- keep rolling.Sum() as a stateful object,
- add values to it incrementally (
rmax.push(val)
) - extract the latest rolling value after every few additions
I see there's a _add_new
, but since calling list(rmax)
is not idempotent, I can't really make this work:
In [19]: l = [1,2,5,7,2,1,2,3,4,5,9,5,5,5,5,3]
In [20]: rmax = rolling.Max(l,3)
In [21]: list(rmax)[-1]
Out[21]: 5
In [22]: rmax._add_new(10)
In [23]: list(rmax)[-1]
IndexError: list index out of range
Edit:
This seems to accomplish what I want, but violates the "only return a value from full window" aspect:
rmax = rolling.Max([], 5)
rmax._update_window(1)
print(rmax.current_value)
rmax._update_window(2)
print(rmax.current_value)
rmax._update_window(3)
print(rmax.current_value)
rmax._update_window(2)
print(rmax.current_value)
rmax._update_window(4)
print(rmax.current_value)
>>>
1
2
3
3
4
Nonetheless I think list(Rolling.*) should be idempotent and perhaps the use of iterators can be reshuffled to support this approach. HTH someone!
Thanks @daikts - that's helpful stuff.
I've had a quick go at implementing this now and opened a PR here if you're interested: #21
The new method allows new values to be added for the rolling object to consume. I chose to call the method extend()
as that seemed more general (and in keeping with adding iterables to the object; cf. Python lists).
If I understood your examples correctly, the new method would allow you to "append" a new value by writing:
rmax.extend([10])
and then advancing the rolling object (e.g. using next
or list
) would include this value in the computation for the new window value.
Let me know what you think!
That seems to work great, thanks for the quick implementation!
No problem! I'll close this issue as resolved now