🌊

Pythonによるデータ可視化_ヒストグラムと箱ひげ図を同時に出力

2023/08/10に公開

経緯

データ分析を行うためにまずはデータを可視化することが多いと思います。
何らかのcsvファイルが与えられた時、dataframeで読み込んだ後、ヒストグラムと箱ひげ図を出力するコードをまとめました。
また可視化を行う過程で外れ値が含まれていることもあると思います。外れ値を除去する場合にも対応できるようにしています。今回は四分位範囲による外れ値検出を行うコードを記載しておきます。
今後も私がデータ可視化のために便利だと思った機能があれば順次追加していきます。

必要なライブラリ

import pandas as pd
import matplotlib.pyplot as plt

外れ値検出用のクラス

# 外れ値検出のクラス
class OutlierRemover:
    def __calclate_min_max(self, data_seriese, coefficient):
        q3 = data_seriese.quantile(0.75)
        q1 = data_seriese.quantile(0.25)
        IQR = q3 - q1
        calc_value = coefficient * IQR
        min_value = q1 - calc_value
        max_value = q3 + calc_value
        return min_value, max_value

    # 引数は元のデータフレーム、外れ値検出を行う列、係数
    def iqr_filtered_series(self, df: pd.DataFrame, column, coefficient=1.5):
        min_value, max_value = self.__calclate_min_max(df[column], coefficient)
        filtered_df = df[ (min_value < df[column]) & (df[column] < max_value) ]
        return filtered_df[column]
    
    # 外れ値として除去したデータフレームを取得したい時に使用するメソッド
    def get_outlier_df(self, df: pd.DataFrame, column, coefficient=1.5):
        min_value, max_value = self.__calclate_min_max(df[column], coefficient)
        improved_outlier_df = df[ (df[column] < min_value) ]
        worsened_outlier_df = df[ (max_value < df[column]) ]
        return improved_outlier_df, worsened_outlier_df

データ可視化用

外れ値検出が不必要であれば、"self.outlier_remover"が含まれている行をコメントアウトすれば動くと思います。

class DataVisualization:
    def __init__(self):
        # 外れ値検出を行うオブジェクト
        self.outlier_remover = ResultsOutlierRemover()
        return
	
    # ヒストグラムと箱ひげ図を列ごとに並べたグラフを作成
    def generate_hist_and_box(self, df, print_columns, remove_outlier=False):
        number_of_columns = len(print_columns)
        # ヒストグラムと箱ひげ図
        unit_of_figure = 2

        # figsizeの引数1が横、引数2が縦
        fig = plt.figure(figsize=(7 * unit_of_figure, 5 * number_of_columns))
        for index, column in enumerate(print_columns):
            data = df[column]
            if remove_outlier == True:
                data = self.outlier_remover.iqr_filtered_series(df, column)
            # axのindexは1から始まることに注意
            ax_index = index * unit_of_figure + 1
            # ヒストグラムの追加
            ax = fig.add_subplot(number_of_columns, unit_of_figure, ax_index)
            ax.hist(data)
            ax.set_title(column)
            # 箱ひげ図の追加
            ax_index = ax_index + 1
            ax = fig.add_subplot(number_of_columns, unit_of_figure, ax_index)
            ax.boxplot(data)
            ax.set_xticklabels([column])
        return fig, ax
    
    def get_summary_df(self, df, print_columns=None, remove_outlier=False):
        # 列の指定がある場合
        if print_columns is not None:
            df = df[print_columns]
        
        summary_df = df.describe()
        if remove_outlier == True:
            columns = summary_df.columns
            for column in columns:
                series = self.outlier_remover.iqr_filtered_series(df, column)
                summary_df[column] = series.describe()
        return summary_df

    def print_summary(self, df, print_columns=None, remove_outlier=False):
        summary_df = self.get_summary_df(df, print_columns, remove_outlier)
        print(summary_df)
        return
    
    def print_and_close(self, fig, ax):
        plt.show()
        plt.close()
        return

    def output_image(self, fig, ax, output_path):
        plt.savefig(output_path)
        plt.close()
        return

使用例

data_pathに使用するデータのpathを代入します。
print_columnsのリストの要素に表示させる列名を指定します。

指定した列のヒストグラムと箱ひげ図をまとめて出力します。
その後、それぞれの列における代表値をまとめて出力します。

import pandas as pd

data_path = "***"
df = pd.read_csv(data_path)
data_visualization = DataVisualization()

print_columns = ["column1", "column2", ..., "column*"]
# 外れ値除去しない場合
fig, ax = data_visualization.generate_hist_and_box(df, print_columns)
data_visualization.print_and_close(fig, ax)
data_visualization.print_summary(df, print_columns)

# 外れ値除去する場合
fig, ax = data_visualization.generate_hist_and_box(df, print_columns, remove_outlier=True)
data_visualization.print_and_close(fig, ax)
data_visualization.print_summary(df, print_columns, remove_outlier=True)

Discussion