How to return a pandas dataframe from an ipywidgets output

Viewed 1561

I have a dataset that I am working on in jupyter notebooks and I would like to be able to access the data as a dataframe that is returned in the ipywidgets output.

I have played around with several options but cannot for the life of me work out how to access the filtered results.

Here is the code that sets up the filters and the listboxes. The full notebook with all the code is here

import pandas as pd
import numpy as np
import ipywidgets as widgets
from ipywidgets import Layout, AppLayout
from IPython.display import display
import functools
 
data = {'year': ['2000', '2000','2000','2000','2001','2001','2001','2001', '2002',  '2002', '2002', '2002',
                 '2003','2003','2003','2003','2004', '2004','2004','2004', '2005', '2005', '2005', '2005', 
                 '2006', '2006', '2006', '2006', '2006', '2007', '2007', '2007', '2007', '2008', '2008', '2008', '2008',
                 '2009', '2009', '2009', '2009'],
        
        'purpose':['Holiday', 'Business', 'VFR', 'Study', 'Holiday', 'Business', 'VFR', 'Study', 'Holiday', 'Business',
                   'VFR', 'Study', 'Holiday', 'Business', 'VFR', 'Study', 'Holiday', 'Business', 'VFR', 'Study', 'Holiday',
                   'Business', 'VFR', 'Study', 'Holiday', 'Business', 'VFR', 'Study', 'Holiday', 'Business', 'VFR', 'Study',
                   'Holiday', 'Business', 'VFR', 'Study', 'Holiday', 'Business', 'VFR', 'Study', 'Holiday'
                  ], 
        
        'market':['Belgium', 'Luxembourg', 'France', 'Spain', 'Norway', 'Sweden', 'Germany', 'Austria', 'Denmark',
                  'Portugal', 'Greece', 'Croatia', 'Belgium', 'Luxembourg', 'France', 'Spain', 'Norway', 'Sweden',
                  'Germany', 'Austria', 'Denmark', 'Portugal', 'Greece', 'Croatia', 'Belgium', 'Luxembourg', 'France',
                  'Spain', 'Norway', 'Sweden', 'Germany', 'Austria', 'Denmark', 'Portugal', 'Greece', 'Croatia', 'Belgium',
                  'Luxembourg', 'France', 'Spain', 'Norway'
                 ]} 
 
df_london = pd.DataFrame (data, columns = ['year','purpose', 'market'])
 
# Get our unique values
ALL = 'ALL'
def unique_sorted_values_plus_ALL(array):
    unique = array.unique().tolist()
    unique.sort()
    unique.insert(0, ALL)
    return unique

output = widgets.Output()

# Dropdown listbox
dropdown_year = widgets.Dropdown(description='Year',
                                  options = unique_sorted_values_plus_ALL(df_london.year))

# Function to filter our dropdown listboxe
def common_filtering(year):
    df = df_london.copy()
        
    filters = []
    
    # Evaluate our dropdown listbox and return booleans for our selections
    if year is not ALL:
        filters.append(df['year'] == year)
    
    output.clear_output()
    
    with output:
        if filters:
            df_filter = functools.reduce(lambda x,y: x&y, filters)
            display(df.loc[df_filter])
        else:
            display(df)

def dropdown_year_eventhandler(change):
    common_filtering(change.new)

dropdown_year.observe(dropdown_year_eventhandler, names='value')

ui = widgets.HBox([dropdown_year])

display(ui, output)

Im sure its a simple one but I just can't work it out myself.

Regards

Tom

1 Answers

The code from a function that you observe can't really return a value in a way that you can use. Alternatively you could set up a global variable, and assign your filtered dataframe to that global variable. I used output_dataframe in the example below.

import pandas as pd
import numpy as np
import ipywidgets as widgets
from ipywidgets import Layout, AppLayout
from IPython.display import display
import functools
 
data = {'year': ['2000', '2000','2000','2000','2001','2001','2001','2001', '2002',  '2002', '2002', '2002',
                 '2003','2003','2003','2003','2004', '2004','2004','2004', '2005', '2005', '2005', '2005', 
                 '2006', '2006', '2006', '2006', '2006', '2007', '2007', '2007', '2007', '2008', '2008', '2008', '2008',
                 '2009', '2009', '2009', '2009'],
        
        'purpose':['Holiday', 'Business', 'VFR', 'Study', 'Holiday', 'Business', 'VFR', 'Study', 'Holiday', 'Business',
                   'VFR', 'Study', 'Holiday', 'Business', 'VFR', 'Study', 'Holiday', 'Business', 'VFR', 'Study', 'Holiday',
                   'Business', 'VFR', 'Study', 'Holiday', 'Business', 'VFR', 'Study', 'Holiday', 'Business', 'VFR', 'Study',
                   'Holiday', 'Business', 'VFR', 'Study', 'Holiday', 'Business', 'VFR', 'Study', 'Holiday'
                  ], 
                'market':['Belgium', 'Luxembourg', 'France', 'Spain', 'Norway', 'Sweden', 'Germany', 'Austria', 'Denmark',
                  'Portugal', 'Greece', 'Croatia', 'Belgium', 'Luxembourg', 'France', 'Spain', 'Norway', 'Sweden',
                  'Germany', 'Austria', 'Denmark', 'Portugal', 'Greece', 'Croatia', 'Belgium', 'Luxembourg', 'France',
                  'Spain', 'Norway', 'Sweden', 'Germany', 'Austria', 'Denmark', 'Portugal', 'Greece', 'Croatia', 'Belgium',
                  'Luxembourg', 'France', 'Spain', 'Norway'
                 ]} 
 
df_london = pd.DataFrame (data, columns = ['year','purpose', 'market'])
 
output_dataframe = None

# Get our unique values
ALL = 'ALL'
def unique_sorted_values_plus_ALL(array):
    unique = array.unique().tolist()
    unique.sort()
    unique.insert(0, ALL)
    return unique

output = widgets.Output()

# Dropdown listbox
dropdown_year = widgets.Dropdown(description='Year',
                                  options = unique_sorted_values_plus_ALL(df_london.year))

        
        
# Function to filter our dropdown listboxe
def common_filtering(year):
    global output_dataframe
    df = df_london.copy()
        
    filters = []
    
    # Evaluate our dropdown listbox and return booleans for our selections
    if year is not ALL:
        filters.append(df['year'] == year)
    
    output.clear_output()
    
    with output:
        if filters:
            df_filter = functools.reduce(lambda x,y: x&y, filters)
            output_dataframe = df.loc[df_filter]
        else:
            output_dataframe = df
        display(output_dataframe)

def dropdown_year_eventhandler(change):
    common_filtering(change.new)

dropdown_year.observe(dropdown_year_eventhandler, names='value')

ui = widgets.HBox([dropdown_year])

display(ui, output)
Related