【问题标题】:Refreshing dataframe in Python inside a While loop在 While 循环内刷新 Python 中的数据框
【发布时间】:2019-10-14 09:04:06
【问题描述】:

我有一个数据框,它从 SQL 中获取数据并根据列的条件发送一封电子邮件。但是这些列在 SQL 中不存在,我需要在创建数据框后创建它们。这里的问题是我有一个 while 循环,它每 10 秒检查一次列的条件。我注意到 while 循环在所有条件下都能完美运行,但数据框没有从 SQL 刷新,因为它位于 while 循环之外。如果我将数据框放在 while 循环中,last_email_sent 会被初始化为None 受到影响并给出错误的输出。下面是我描述逻辑的伪代码。

#initialisation and fetching of the table from SQL
df = pd.read_sql('SELECT * FROM stations', cnxn)
df['Timeflag'] = now - df['last_reported']
df['last_email_sent'] = None

while True:
   for index in df.index:
       if(df['Timeflag'] == 1 and df.loc[df.index[index], "Last_email_sent"] is None:
            print('pass')
            minutes = divmod((now - df.loc[index, "Last_email_sent"]).total_seconds(), 60)[0]

       elif df.loc[index, 'Time flag'] == 1 and minutes < min:
            print('fail')
            minutes = divmod((now - df.loc[index, "Last_email_sent"]).total_seconds(), 60)[0]
               else:
        print('false')
time.sleep(10)  

问题是我不能做类似下面的事情,因为在 for 循环中 last_email_sent 不能是 None 并且必须保留在第一次循环循环后流行的最后更新值。

while True:
    #initialisation and fetching of the table from SQL
    df = pd.read_sql('SELECT * FROM stations', cnxn)
    df['Timeflag'] = now - df['last_reported']
    df['last_email_sent'] = None

有没有其他方法可以在for循环中调用数据框,从而同时计算其他列?

【问题讨论】:

    标签: python sql python-3.x pyodbc


    【解决方案1】:

    如果我以正确的方式解决了您的问题,您可以执行以下操作,但请注意它尚未准备好使用代码,我只是想演示逻辑

    First_Start = True  # first time we define db colum to None
    Last_Email_Sent = None  # when we sent the last email
    
    while True:
    
        # read data from db heare and do what you need
        df = pd.read_sql('SELECT * FROM stations', cnxn)
        df['Timeflag'] = now - df['last_reported']
        if First_Start:
            df['last_email_sent'] = None
            First_Start = False  # never again will be True
        else:
            df['last_email_sent'] = Last_Email_Sent
    
        while True:
           for index in df.index:  # cheack all you want in df
               if(df['Timeflag'] == 1 and df.loc[df.index[index], "Last_email_sent"] is None:
                    print('pass')
                    minutes = divmod((now - df.loc[index, "Last_email_sent"]).total_seconds(), 60)[0]
    
               elif df.loc[index, 'Time flag'] == 1 and minutes < min:
                    print('fail')
                    minutes = divmod((now - df.loc[index, "Last_email_sent"]).total_seconds(), 60)[0]
                else:
                    print('false')
    
            Last_Email_Sent  = ??? # define new value here!
            break # all work is done and you go out of the while loop
        time.sleep(10)
    
        # now you can apply to db again to get a new df
    

    希望答案对你有用。

    【讨论】:

    • 感谢您的帮助。最后我可以分配 Last_Email_Sent = df['last_email_sent'] 因为那是我想要的。这是正确的分配方式吗? @Artiom Kozyrev
    • @KrishnamurthyKA 为什么不呢? Last_Email_Sent 可以是您想要的任何值,您当然可以将 df 列与另一个 df 列进行比较。如果我的回答有帮助,请点赞,如果问题已解决,请将 anser 标记为解决方案。
    • 如何将列分配给变量?在 while 循环结束时 First_start 应该为假,对吗?因为它不会第二次触发 else 部分。我仍在测试我的代码。 @Artiom Kozyrev
    • @KrishnamurthyKA 为什么你不能? df 的列也是您可以分配的变量。第一次启动在第一次运行时为真,在所有其他情况下为假,它肯定会触发其他。如果 First_Start 部分是正确的: df['last_email_sent'] = None First_Start = False # never again will be True else: df['last_email_sent'] = Last_Email_Sent
    • @KrishnamurthyKA 你好,复试怎么样?
    猜你喜欢
    • 1970-01-01
    • 2021-05-27
    • 1970-01-01
    • 2014-11-02
    • 1970-01-01
    • 2015-02-24
    • 2014-03-22
    • 1970-01-01
    • 2021-02-27
    相关资源
    最近更新 更多