Pandas df.style.applymap在schedule调度模式下着色失效问题解决
DataFrame单元格着色在schedule定时任务中失效的解决方法
单独运行时,使用df.style.applymap可正常为DataFrame的「內盤」「外盤」单元格着色;但将逻辑放入schedule定时任务(每20秒执行)的函数中时,着色功能失效,最终通过将display(df)替换为display(df.style.applymap(...))的方式解决问题。
一、正常运行的代码
import pandas as pd import numpy as np import datetime import schedule import time ticks = api.ticks(api.Contracts.Stocks["2330"], "2022-08-12") df = pd.DataFrame({**ticks}) df.ts = pd.to_datetime(df.ts) df['成交時間'] = df['ts'].dt.strftime('%Y/%m/%d %H:%M:%S') #調整格式 df['ask_price'] = df['ask_price'].map('${:,.1f}'.format) #調整格式 df['close'] = df['close'].map('${:,.1f}'.format) #調整格式 df['bid_price'] = df['bid_price'].map('${:,.1f}'.format) #調整格式 df = df.drop(["ts"], axis=1) #取消不需要欄位 df = df.drop(["tick_type"], axis=1) #取消不需要欄位 df = df.drop(["ask_volume"], axis=1) #取消不需要欄位 df = df.drop(["bid_volume"], axis=1) #取消不需要欄位 df = df[df.volume>200] conditions = [df["close"] == df["ask_price"]] #條件:收盤等於外盤 choices = ['外盤'] df['外盤'] = np.select(conditions, choices, default='-') conditions = [df["close"] == df["bid_price"]] #條件:收盤等於內盤 choices = ['內盤'] df['內盤'] = np.select(conditions, choices, default='-') df = df[['成交時間', 'ask_price', 'close', 'bid_price', 'volume','外盤','內盤']] #欄位指定順序 df = df.sort_values(["成交時間"], ascending=False) #依時間欄排序, 近的在上, 遠的在下 df.style.applymap(lambda x: "background-color: green" if x == "內盤" else "background-color: red" if x == "外盤" else "background-color: black")
二、定时任务中着色失效的代码
import pandas as pd import numpy as np import datetime import schedule import time from IPython.display import display # 额外导入 def show_datafr(): ticks = api.ticks(api.Contracts.Stocks["2330"], "2022-08-12") df = pd.DataFrame({**ticks}) df.ts = pd.to_datetime(df.ts) df['成交時間'] = df['ts'].dt.strftime('%Y/%m/%d %H:%M:%S') #調整格式 df['ask_price'] = df['ask_price'].map('${:,.1f}'.format) #調整格式 df['close'] = df['close'].map('${:,.1f}'.format) #調整格式 df['bid_price'] = df['bid_price'].map('${:,.1f}'.format) #調整格式 df = df.drop(["ts"], axis=1) #取消不需要欄位 df = df.drop(["tick_type"], axis=1) #取消不需要欄位 df = df.drop(["ask_volume"], axis=1) #取消不需要欄位 df = df.drop(["bid_volume"], axis=1) #取消不需要欄位 df = df[df.volume>200] conditions = [df["close"] == df["ask_price"]] #條件:收盤等於外盤 choices = ['外盤'] df['外盤'] = np.select(conditions, choices, default='-') conditions = [df["close"] == df["bid_price"]] #條件:收盤等於內盤 choices = ['內盤'] df['內盤'] = np.select(conditions, choices, default='-') df = df[['成交時間', 'ask_price', 'close', 'bid_price', 'volume','外盤','內盤']] #欄位指定順序 df = df.sort_values(["成交時間"], ascending=False) #依時間欄排序, 近的在上, 遠的在下 df.style.applymap(lambda x: "background-color: green" if x == "內盤" else "background-color: red" if x == "外盤" else "background-color: black") display(df) # 显示DataFrame schedule.every(20).seconds.do(show_datafr) while True: schedule.run_pending() time.sleep(1)
三、问题分析与解决方法
问题原因
单独运行时,Jupyter环境会自动渲染df.style.applymap返回的Styler对象;但在schedule定时任务的函数中,仅调用df.style.applymap而不将其传入display(),只会生成Styler对象却不执行渲染,最后display(df)显示的是未应用样式的原始DataFrame,导致着色失效。
解决方法
直接将样式应用后的Styler对象传入display(),替代原有的display(df)。
四、修改后的关键代码
display(df.style.applymap(lambda x: "background-color: green" if x == "內盤" else "background-color: red" if x == "外盤" else "background-color: black"))
内容的提问来源于stack exchange,提问作者David Lin
相关产品推荐
相关产品推荐

