Python グラフ化/複数列抽出/列計算/列方向連結/列方向ソートする方法「pandas」

 本記事に記載してるコードの仕様説明をします。下図のようなcsvファイルがある。

aaa,bbb,y,x,ccc
0.01,1,100,1,10
0.025,2,40,2.5,9
0.05,3,20,5,8
0.075,4,13.33333333,7.5,7
0.1,5,10,10,6
0.2,6,5,20,5
0.3,7,3.333333333,30,4
0.4,8,2.5,40,3
0.5,9,2,50,2
0.6,10,1.666666667,60,1
0.7,11,1.428571429,70,0
0.8,12,1.25,80,-1
0.9,13,1.111111111,90,-2
1,14,1,100,-3

▼1. pandasのデータフレーム型で読み込んだ後に、x軸とy軸にする2列を指定して下図のように散布図を作成する

f:id:HK29:20200322234813p:plain

そして、次の2~5のようなcsvファイルを作成します。
▼2. 下図のようにx,y列の2列の値で平均二乗和(root mean square, RMS)を計算して、RMSの列を作成する

f:id:HK29:20200323001124p:plain

▼3. 元のcsvファイルにRMSの列を連結する

f:id:HK29:20200323001154p:plain

▼4. RMSが最小と最大の行を抽出

f:id:HK29:20200323001227p:plain

▼5. 転置

f:id:HK29:20200323001301p:plain

■本プログラム

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os, math
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

def main():
    # csv ファイルの読み込み
    df = pd.read_csv(file_path, skiprows=0, encoding='utf-8')
    print(df)

    # 散布図
    my_fontsize = 12
    fig = plt.figure(figsize=(6, 4)) # 横, 縦
    ax = fig.add_subplot(1,1,1)
    ax.scatter(x=df[target_columns[0]], y=df[target_columns[1]], label='data')
    ax.set_xlim(0, 110)
    ax.set_ylim(0, 110)
    ax.set_xticklabels(ax.get_xticks(), rotation=45)
    ax.set_xlabel(target_columns[0], fontsize = my_fontsize)
    ax.set_ylabel(target_columns[1], fontsize = my_fontsize)
    ax.set_title('title', fontsize = my_fontsize)
    plt.legend()
    plt.grid()
    plt.tick_params(labelsize = my_fontsize) # 目盛りのサイズ
    plt.tight_layout() # ラベルが収まるように調整
    #plt.show()
    fig.savefig("graph.png")
    plt.close()
    
    # 複数列を抽出
    target_df = df[target_columns]
    print(target_df)
    
    # 2乗平均平方根を計算
    target_df['RMS'] = (pow(target_df.abs(), 2)).sum(axis=1).apply(math.sqrt)
    print(target_df)
    target_df.to_csv(file_path[:-4] + '_01_RMS.csv', sep=',', index=False, encoding='utf-8', header=True)
    
    # 元のdfと列方向へ連結する
    rms_df = pd.concat([df, target_df], axis=1)

    # RMSでソートする。複数列で並び替えしたい場合はリストで与える。例['RMS','bbb']
    sort_df = rms_df.sort_values(by='RMS', ascending=True)
    sort_df.to_csv(file_path[:-4] + '_02_connect_and_sort.csv', sep=',', index=False, encoding='utf-8', header=True)

    # RMSが最小値の行を抽出する
    min_row = rms_df['RMS'].idxmin() # 列名[RMS]の最小値のインデックス(行名)を返す
    print('min_row', min_row)

    # RMSが最大値の行を抽出する
    max_row = rms_df['RMS'].idxmax() # 列名[RMS]の最大値のインデックス(行名)を返す
    print('max_row', max_row)
    
    # 行名指定で抽出
    min_data_series = sort_df.loc[min_row]
    print(min_data_series)
    print(type(min_data_series))
    max_data_series = sort_df.loc[max_row]
    print(max_data_series)
    print(type(max_data_series))
    
    # pandas形式のSeries型の列の連結
    DF = pd.concat((min_data_series.rename('min_data'), max_data_series.rename('max_data')), axis=1, sort=False)
    print(DF)
    DF.to_csv(file_path[:-4] + '_03_RMS_min_max.csv', sep=',', index=True, encoding='utf-8', header=True)

    # 転置
    DF_T = DF.T
    print(DF_T)
    DF_T.to_csv(file_path[:-4] + '_04_RMS_min_max_T.csv', sep=',', index=True, encoding='utf-8', header=True)
    
if __name__ == '__main__':
    path = os.getcwd()       # currenet directry
    input_file = 'Hyperbola.csv'
    file_path = os.path.join(path, input_file)
    target_columns = ['x', 'y']

    main()
    print('finished')

以上

<広告>