Ranking of dataframe by considering various combination of features(columns)

Viewed 107

I have a pandas dataframe which has 4 columns and looks like

import plotly.express as px
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

data = pd.read_excel('disparity.xlsx')
data.head()

dataframe

Then I plot the stacked barplot using plotly.

px.bar(data.head().set_index('COUNTY'))

The output is Stacked barchart

But I want this stacked barchart is shown in either descending or ascending order. Also, along with three columns, I also want to plot ranked stacked bar chart by taking two columns one at a time i.e. (COVID death, diabetic); (COVID death, Obesity) and (Obesity, diabetic).

Hence I actually want to plot a total 4 ranked stacked barplot. Please help me in this regard.

2 Answers

The idea is calculating the key to sort by for each row, adding that as a new column to the DataFrame, and use DataFrame.sort_values to sort by that. (Unfortunately there is no easy way right now to sort the dataframe by an external Series without adding it as a column.)

First, let's set the index permanently, and save the list of original features:

data.set_index('COUNTY', inplace=True)
original_features = list(data.columns)

To sort by total height, first add an extra column to the dataframe with the sum for each row

data["Total"] = data.sum(axis='columns')

and sort by that (but removing the "Total" column out of the plot):

px.bar(data.sort_values("Total", ascending=True)[original_features])

You can control ascending/descending with the ascending parameter.

As another example, sort by "COVID Deaths" + "Diabetic":

data["COVID + Diabetic"] = data["COVID Death"] + data["Diabetic"]
px.bar(data.sort_values("COVID + Diabetic", ascending=True)[original_features])

Since you mentioned you want to sort by the sum of every pair of columns, you can automate that with a loop:

import itertools

for x, y in itertools.combinations(original_features, 2):
    name = f"{x} + {y}"
    data[name] = data[x] + data[y]
    px.bar(data.sort_values(by=name, ascending=True)[original_features])

In fact, you can generalise this to any number of features; i.e. if you want one plot for the sum of each subset of features (i.e. every single feature, every pair, etc., up to the total), you can do:

import operator
from functools import reduce

for k in range(1, len(original_features) + 1):
    for comb in itertools.combinations(original_features, k):
        name = " + ".join(comb)
        data[name] = reduce(operator.add, (data[col] for col in comb))
        # optional: reorder the columns so that the ones we're sorting by come first
        order = list(comb) + [col for col in original_features if col not in comb]
        px.bar(data.sort_values(by=name, ascending=True)[order])

Try this:

for column_name, column_series in df.iloc[:, 1:].iteritems():
    fig = px.bar(df, x='COUNTY', y=column_name)
    fig.show()
Related