Python: ipywidgets 不显示输出

Python: ipywidgets not showing output

我写了一个 python 脚本,它应该有一个数据框作为输出,但它没有显示任何输出。下面是 python 代码:

import pandas as pd
import numpy as np
import ipywidgets as widgets
import datetime
from ipywidgets import interactive
from IPython.display import display, Javascript
from datetime import date, timedelta
from random import choices
  

books = ["Book_1","Book_2","Book_3","Book_4","Book_5"]
counterparties = ["Counterparty_1","Counterparty_2","Counterparty_3","Counterparty_4","Counterparty_5"]

book = choices(books, k = 100)
counterparty = choices(counterparties, k = 100)


date1, date2 = date(2018, 8, 1), date(2023, 8, 3)
  
res_dates = [date1]
  
while date1 != date2:
    date1 += timedelta(days=1)
    res_dates.append(date1)
  
ldd = choices(res_dates, k=100)

dict = {'book': book, 'counterparty': counterparty, 'last_trading_date': ldd} 

df = pd.DataFrame(dict)



books = pd.Categorical(df['book'])
books = books.categories

books_dropdown = widgets.Dropdown(
    options=books,
    value=books[0],
    description='Book:',
    disabled=False,
)


counterparty = pd.Categorical(df['counterparty'])
counterparty = counterparty.categories

counter_dropdown = widgets.Dropdown(
    options=counterparty,
    value=counterparty[0],
    description='Counterparty:',
    disabled=False,
)


date_picker = widgets.DatePicker(
    description='Pick a Date',
    disabled=False,
)
date_picker.add_class("start-date")

script = Javascript("\
                const query = '.start-date > input:first-of-type'; \
                document.querySelector(query).setAttribute('min', '2020-12-01'); \
                document.querySelector(query).setAttribute('max', '2025-01-01'); \
        ")


box = widgets.VBox([books_dropdown, counter_dropdown, date_picker])
display(box)

def filter_function(bookcode, cpartycode, datecode):
        
    filtered = df[(df['book'] == bookcode) & (df['counterparty'] == cpartycode)]
    
    x = datetime.date(datecode.value)
    
    filtered = filtered[filtered['last_trading_date'] < x]
    
    with report_output:
        report_output.clear_output()
        display(filtered)
        
interactive(filter_function, bookcode=books_dropdown, cpartycode=counter_dropdown, datecode=date_picker) 

report_output = widgets.Output()
display(report_output)

这基本上是获取一个数据框,根据两个变量的类别将所述数据框子集化为更小的数据框,并根据用户选择的日期截断生成的数据框。

我是不是哪里弄错了?如果是这样,有人可以指出我在哪里吗?提前谢谢你。

编辑:

经过多次尝试,我得出的结论是问题与 DatePicker 小部件有关。因此,您在尝试解决问题时可以专注于此。

如果我理解正确,这是我用来重现问题的代码:

from datetime import date, timedelta
from random import choices 
import pandas as pd
import ipywidgets as widgets
import datetime
from ipywidgets import interactive
from IPython.display import display, Javascript

books = ["Book_1","Book_2","Book_3","Book_4","Book_5"]
counterparties = ["Counterparty_1","Counterparty_2","Counterparty_3","Counterparty_4","Counterparty_5"]

book = choices(books, k = 100)
counterparty = choices(counterparties, k = 100)


date1, date2 = date(2018, 8, 1), date(2023, 8, 3)
  
res_dates = [date1]
  
while date1 != date2:
    date1 += timedelta(days=1)
    res_dates.append(date1)
  
ldd = choices(res_dates, k=100)

dict = {'book': book, 'counterparty': counterparty, 'last_trading_date': ldd} 

df = pd.DataFrame(dict)

df['last_trading_date'] = pd.to_datetime(df['last_trading_date'], format = '%Y-%m-%d').dt.date


books = pd.Categorical(df['book'])
books = books.categories

books_dropdown = widgets.Dropdown(
    options=books,
    value=books[0],
    description='Book:',
    disabled=False,)

counterparty = pd.Categorical(df['counterparty'])
counterparty = counterparty.categories

counter_dropdown = widgets.Dropdown(
    options=counterparty,
    value=counterparty[0],
    description='Counterparty:',
    disabled=False,
)

date_picker = widgets.DatePicker(
    description='Pick a Date',
    disabled=False,
)

date_picker.add_class("start-date")

script = Javascript("\
                const query = '.start-date > input:first-of-type'; \
                document.querySelector(query).setAttribute('min', '2020-12-01'); \
                document.querySelector(query).setAttribute('max', '2025-01-01'); \
        ")

def filter_function(bookcode, cpartycode, datecode):
        
    filtered = df[(df['book'] == bookcode) & (df['counterparty'] == cpartycode)]
    
    filtered = filtered[filtered['last_trading_date'] < datecode]
    
    with report_output:
        report_output.clear_output()
        display(filtered)  
        
w = interactive(filter_function, bookcode=books_dropdown, cpartycode=counter_dropdown, datecode=date_picker) 

display(w)
report_output = widgets.Output()
display(report_output)

使用 Jupyter Notebook 中代码为 运行 时显示的小部件,我得到以下输出:

我在您提供的代码中所做的唯一更改是:

  1. 删除 VBox 的代码。
  2. 将交互式小部件存储为变量并使用 display() 显示它。
  3. 直接使用 filtered_functiondatecode 参数来创建 filtered 而不是使用 datetime.date(datecode.value).