IPywidgets динамически привязывает виджеты к выходу

#python #pandas #jupyter-notebook #ipywidgets

#python #панды #jupyter-ноутбук #ipywidgets

Вопрос:

Я пишу функцию для ноутбуков Jupyter, где пользователь сможет получать данные в виде фрейма данных Pandas (не имеет значения для этого вопроса) и отображать их с помощью фильтров, которые он мог бы создать при необходимости.

Моя проблема в том, что я не могу «связать» фильтр взаимодействия с самими данными. У меня не было проблем с ручным определением фильтров в коде, но не со стороны пользователя. Перед публикацией здесь я изучил множество вопросов из Stackoverflow, Google, project Github и docs.

Вот POC:

 import pandas as pd
import ipywidgets as widgets
from ipywidgets import *
from IPython.display import display
import numpy as np

np.random.seed(0)

# Data example
my_columns = list('ABCD')
df = pd.DataFrame(np.random.randint(0,100,size=(100, 4)), columns=list('ABCD'))


# Encapsulate Table inside Output widget

table_out = widgets.Output()

with table_out:
    display(df)


# Filter for ints
def filter_int(column, x):
    return df.loc[df[column] > x]

# Our filter generator
def generate_filter(button):
    # Check if exist before creating
    if not select_definition.value in [ asd.children[0].description for asd in filters.children ]:
        # Not exist. Create this filter
        new_filter = interactive(
            filter_int, # Our filter for ints
            column=fixed(select_definition.value), # Which column as filter
            x=widgets.IntSlider(min=0, max=100, step=1, value=10, description=select_definition.value) # Value from the user
        )
        # Append created filter
        filters.children=tuple(list(filters.children)   [new_filter])

# Define button and event
button = widgets.Button(description="Add")
button.on_click(generate_filter)

# Define Dropdown 
select_definition = widgets.Dropdown(options=my_columns, layout=Layout(width='10%'))

# Put Dropdown and button together
choose_filter = widgets.HBox([select_definition, button])

# Where we will put all our filters
filters = widgets.HBox()

display(choose_filter, filters, table_out)
  

Что создаст это:

введите описание изображения здесь

Я могу динамически создавать фильтры для столбцов, но я не уверен, как заставить их обновлять таблицу и связывать ее вместе (поэтому таблица будет обновляться на основе нескольких фильтров).

Ожидаемый результат — возможность создавать фильтры для столбцов A B и обновлять таблицу значениями, определенными ими, как показано на рисунке ниже:

введите описание изображения здесь

Любая помощь приветствуется!

Примечание: Последнее изображение было сгенерировано с df.loc[(df['A'] > 22) amp; (df['B'] > 92)]

Комментарии:

1. Я думаю, что то, что вы создаете, может быть слишком сложным для простого interact вызова, особенно когда виджеты генерируются динамически. Я предлагаю создать класс, который может содержать различные виджеты фильтрации, выпадающий список и обрабатывать динамическое создание, а затем заставить ваш фрейм данных реагировать на этот класс.