Issue
What I'm trying to do is updating a Dataframe in two intervals of different lengths.
Update 1 changes the last row of the df with an interval of 0 - 2 seconds, generated in the Signal
class,
Update 2 is generated in change_hist_data()
and alters the rows 0 - 4 in a 5 second interval.
The problem with my code is that the interval of the change of data occurs on the entire df in the speed of the pulse
in the Signal
class.
What I want is that row 0 - 4 updates in 5 second intervals, only the last row in the faster pace.
What am I doing wrong?
Btw, if someone likes to give me an additional tipp - will the sys.stdout.write("\033[F")
run smoothly long term ( weeks or months) ? I notice that sometimes the column name shifts a bit back and forth
import pandas as pd
import time
import random
import numpy as np
import sys
import asyncio
class Signal:
def __init__(self):
pass
def pulse(self):
while True:
x = random.uniform(0,2)
y = random.uniform(1,9)
time.sleep(x)
self.pulse = y
return self.pulse
async def change_hist_data():
while True:
task1 = asyncio.create_task(print_df())
await asyncio.sleep(5)
data = np.random.rand(6,1)
return data
async def print_df():
while True:
task2 = asyncio.create_task(change_hist_data())
df = pd.DataFrame(await task2, columns={'data'})
p = Signal()
p = p.pulse()
df.data.iloc[-1] = p
print(df)
sys.stdout.write("\033[F")
sys.stdout.write("\033[F")
sys.stdout.write("\033[F")
sys.stdout.write("\033[F")
sys.stdout.write("\033[F")
sys.stdout.write("\033[F")
sys.stdout.write("\033[F")
asyncio.run(print_df())
Update:
I came up with this solution based on Peter Cornelius input and my initial idea. The df
is now printing in both intervals. Actually the method name random_delay
is not appropriate anymore as I set it to a fix interval of 0.2 seconds.
import random
import asyncio
import pandas as pd
import numpy as np
import sys
class DataFrameWrapper:
def __init__(self):
self.data = self.update_rows0_to_4()
self.df = pd.DataFrame(self.data, columns={'data'})
def update_row5(self):
self.pulse = random.uniform(0,2)
return self.pulse
def update_rows0_to_4(self):
self.data = np.random.rand(6,1)
return self.data
async def random_delay(df_wrapper):
while True:
df_wrapper.df.data.iloc[-1] = df_wrapper.update_row5()
print(df_wrapper.df)
sys.stdout.write("\033[F")
sys.stdout.write("\033[F")
sys.stdout.write("\033[F")
sys.stdout.write("\033[F")
sys.stdout.write("\033[F")
sys.stdout.write("\033[F")
sys.stdout.write("\033[F")
await asyncio.sleep(0.2)
async def delay_5s(df_wrapper):
while True:
df_wrapper.df.data = df_wrapper.update_rows0_to_4()
print(df_wrapper.df)
sys.stdout.write("\033[F")
sys.stdout.write("\033[F")
sys.stdout.write("\033[F")
sys.stdout.write("\033[F")
sys.stdout.write("\033[F")
sys.stdout.write("\033[F")
sys.stdout.write("\033[F")
await asyncio.sleep(5.0)
df_wrapper = DataFrameWrapper()
async def main():
await asyncio.gather(random_delay(df_wrapper),delay_5s(df_wrapper) )
asyncio.run(main())
Solution
You've given a nice description of the problem, but the structure of your program isn't right. You need something like this:
import random
import asyncio
class DataFrameWrapper:
def __init__(self, df):
self.df = df
def update_row5(self):
print("Updating row 5")
def update_rows0_to_4(self):
print("Updating row 0-4")
async def random_delay(df_wrapper):
while True:
x = random.uniform(0.0, 2.0)
await asyncio.sleep(x)
df_wrapper.update_row5()
async def delay_5s(df_wrapper):
asyncio.create_task(random_delay(df_wrapper))
while True:
await asyncio.sleep(5.0)
df_wrapper.update_rows0_to_4()
# df is some dataframe
df_wrapper = DataFrameWrapper(df)
asyncio.run(delay_5s(df_wrapper))
Here, the periodic time delay functions are two asyncio tasks. They periodically execute function calls back to the data frame object, where you can manipulate your data. I haven't tried to include any details there - I've just stubbed out those functions.
In your first while loop, you call time.sleep, which blocks the asyncio event loop. So that's not a task, and therefore it will not cooperate with the coroutine change_hist_data.
Neither of your first two while loops are really loops, since you always return at the end of the loop.
Answered By - Paul Cornelius
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.