pandas

公式ドキュメント

https://pandas.pydata.org/docs/


インストールとインポート

インストール

py -m pip install pandas

インポート

import pandas as pd

ファイル入出力

CSVファイルの読み込み

CSVファイルをDataFrameに読み込む。

df1 = pd.read_csv(csv_file, dtype={'data_column':str, 'facility_cd':str})
  • dtyp:カラム名を指定して、データ型を指定することができる。カラム名を省略すればファイル全体のデータ型が指定できる。(指定されたカラム以外は自動で選択された型になる)
  • カラム名はCSVファイルの1行目にあることを想定する。

CSVファイルへの書き込み

df3.to_csv(output_trace_possavs_file, header=True, index=True,columns=['column1','column2'])
  • ヘッダー(header)を1行目に追加するかしないかを”header=True/False”で、インデックス(行番号)を1列目に追加するかしないかを”index=True/False”で指定できる。DefaulthaどちらもTrueである。
  • 1列目にインデックス(行番号)を追加するかしないかをTrue/Falseで指定できる。(Default=True)
  • 特定のカラムだけを書き出すときは、”columns=[]”にリストで指定する。
  • 出力したCSVファイルをExcelで開くと、1行毎に余分に改行されてブランク行が入ることがある(OSの改行文字の違いの影響)。そのときはパラメーターに”line_terminator=’\n'”を付け加えるとよい。

Excelファイルに書き出す

DataFrameをExcelファイルとして書き出す。

df2.to_excel('C:\\Users\\m\\Downloads\\temp1.xlsx', sheet_name='sheet2',  index=False, header=True))
  • ファイル名:存在する場合は上書き、ない場合は新規作成される。
  • sheet_name:省略するとSheet1になる。
  • index/header:書き出さないときはFalseにする.

復数のDataFrameをExcelファイルに書き出す

1つのwith文で、1つのExcelファイルに復数のDataFrameから書き出すことができる。

新規作成または上書きの場合はto_execlが使えるが、既存のExcelファイルに追記する場合はExcelWriterを使う。(おそらく正式なExcelエンジンを使用する必要があるため。)

with pd.ExcelWriter(database+'_csv.xlsx', engine='openpyxl', mode=mode1) as writer:
    csv_data.to_excel(writer, sheet_name=csvfile, index=False)
  • pandas.ExcelWriter()にファイル指定してExcelWriterオブジェクトを生成し、to_excel()メソッドの第一引数にExcelWriterオブジェクトを指定する。

表示コマンド

行数・列数の表示

infoメソッドで行数・列数や全体のメモリ使用量、各列のデータ型や欠損値ではない要素の数などの情報を表示できる。

df.info()

DataFrameのshape属性は行数と列数をタプルを返す。

print(df.shape)

最初・最後の5行を表示する

df.head(), df.tail()

カッコ内に数値を書いて行数を指定できる。

カラムを指定して表示する

df[['Age']]

すべての行(:)の、カラム0から3の手前までの列を表示する

df.iloc[:,0:3]

条件に一致した行がTrue/Falseで表示される

df['Gender'] == 'Male'

上記コマンドを更に’df[]’で囲むと、カラム’Gender’が’Male’と一致するRowを表示してからカウントを表示

df[df['Gender'] == 'Male']

Dataframeの空を判断

pandas.DataFrameやSeriesが空かどうかを判定する。TrueかFalseが返る。

DataFrameに値がある間実行する場合:

while (dataframe2.empty == False):

並び替え

Sort

特定のカラムでSortして新しいDataFrameを返す。

df2 = df1.sort_values(by='date',ascending=True)

複数のFieldを指定する場合は、以下のように記述する。

df1.sort_values(by=['facility_cd','date','id','time'], inplace=True)

Defaultでは元のData Frameは更新されず、新しいData Frameを返す。元のData Frameを更新する場合は、”inplace=True”をオプションに追加する。(ただしPandasのメモリーは、CopyとViewがあるので注意が必要。)

  • by:Sortするカラムを指定する。
  • ascending:TrueかFalse

行・列の編集

行の削除

ラインの削除はインデックスを指定して以下のように行う。

df.drop([0, 1])
df.drop(index=[0, 1])
  • “axis=0″がDefaultなので指定しなくてもよい。
  • DataFrameを返す。”inplace=True”を指定すると元のDataFrameが変更されて何も返さない。

列の削除

カラムの削除はカラム名を指定して以下のように行う。

df.drop(['B', 'C'], axis=1)
df.drop(columns=['B', 'C'])
  • “axis=0″がDefaultなので、列の削除では”axis=1″を指定するか、”columns=”を使う必要がある。
  • DataFrameを返す。”inplace=True”を指定すると元のDataFrameが変更されて何も返さない。

データ型の変換

astype()

df_mean_plan_time['customer_number'] = df_mean_plan_time['customer_number'].astype(str)

使えるdata typeは、Pythonのデータ型以外にPandaasのデータ型が使えるが、Python型を指定した場合、自動的にPandasのデータ型に変換される(str→objectなど)。

Float型

Float型に変換する場合:

dataframe2[f'{lat}'] = dataframe2[f'{lat}'].astype(float)

Datetime型

dataframeの文字列を日付型に変換する。

pd.to_datetime(dataframe1['ride_time'])).dt.seconds / 60
  • 元の文字列を日付型に変換する。
  • 更に変換された日付型データをdtアクセサーでSecond, Microsecond, Dayの単位に変換する。
df_plan_time['plan_time'] = pd.to_datetime(df_plan_time['plan_time'], format='%H:%M:%S')
  • formatで必要な形式に変換する。

日付から曜日を求める

df_plan_time['dayofweek'] = df_plan_time['date'].dt.dayofweek
  • 日曜:0 ~ 土曜:6までが返ってくる。

ユニーク

ユニークカラム抽出

DataFrameの特定のカラムのユニークなものを返す。

uniq_facility_cd = df1['facility_cd'].unique()

ユニークな要素数

df1['facility_cd'].nunique()

ユニークな要素の度数(出現回数)

df1['facility_cd'].value_counts()

DataBase的操作

カラムの選択

SQLクエリのSELECTは、以下の方法で行う。

save1 = df1[['date','facility_cd']]

queryでもカラムを条件をつけて選択することができる。

df2 = df1.query('facility_cd ==  @facility_cd_select')
  • 条件の中で変数を使うときは、頭に”@”を付ける。
dataframe1 = dataframe1.query(f'@list_values[0] <= {col_name[0]} <= @list_values[1]')
  • カラム名を変数にするときは、f文字列を使う。(Python 3.6以降)

Merge

クエリのjoin leftと同じことができる。

df_merged = pd.merge(bindatad1, mergedata1, how='left', on=['facility_cd', 'customer_number','date','pickup_dropoff_category'])

Join

leftとrightを指定できる。

df_a_visitschedule_car = df_a_visitschedule.join(df_car, on='car_number', how='left', lsuffix='_1', rsuffix='_2')
  • on : キーになるカラムを指定する。
  • how : Join方法を選択する。Defaultはleftで、その他に ‘right’, ‘outer’, ‘inner’, ‘cross’が選べる。
  • lsuffix : 同じ名前のカラムがあったときに、Left側のカラムに付けられるSuffix文字。
  • rsuffix : 同じ名前のカラムがあったときに、Rught側のカラムに付けられるSuffix文字。

Concat

公式ドキュメント→pandas.concate

df_merged = pd.concat([df_merged,df1])

リストに指定されたDataFrameがConcatenateされる。2個以上指定することができる。

カラムデータによってDataFrameを分ける

1つのカラムの値によって、DataFrameを分割することができる。

df_merged1 = df_merged[df_merged.pickup_dropoff_category==1]
df_merged2 = df_merged[df_merged.pickup_dropoff_category==2]
# Monday
df_plan_time['sunday_plan_time'] = df_plan_time['plan_time'].where(df_plan_time['dayofweek'] == 0)
# Tuesday
df_plan_time['monday_plan_time'] = df_plan_time['plan_time'].where(df_plan_time['dayofweek'] == 1)

dataframe.apply

SQLクエリのWHEREと同様の処理ができる。DataFrameの値によって異なる処理を行う事ができる。

lambdaを使う場合

条件分岐が少ない場合は、lambdaで簡単にかける。

dataframe1['plan-ride'] = dataframe1['plan-ride'].apply(lambda x : x if x < 1000 else x-1440)

関数を使う場合

条件が多くなるとlambdaでは見にくいので、別途関数を用意するとよい。

def func1(x):
if (x < 1000):
return x
else:
return x - 1440

dataframe1['plan-ride'] = dataframe1['plan-ride'].apply(func1)
  • applyには関数名だけ書く。
  • 関数の定義で、DataFrameの値をxとして条件によって返す値を変更する。

計算

各カラムの平均を求める

df.mean()

カラムごとの平均や標準偏差を一気に表示する

df.describe()
表示名説明Pandasで相当する関数
countデータの個数を表します。DataFrame.count,Series.count
mean数値データの平均を表します。DataFrame.mean,Series.mean
std数値データの標準偏差を表します。DataFrame.std, Series.std
min最小値を表します。DataFrame.min,Series.min
max最大値を表します。DataFrame.max,Series.max
25%,50%,75%四分位数を表します。(区切る部分はpercentiles引数で変更可能)DataFrame.quantile,Series.quantile
https://deepage.net/features/pandas-describe.html

50%が中央値(Median)になる。

ヒストグラム

import pandas as pd
import matplotlib.pyplot as plt

#Histgram
# Plot by Pandas Hist Function
df1['age'].hist(grid=True, xrot=90, bins=90, range=[40,130])

# Show Plot on Screen
plt.show()

# Save PNG File
plt.savefig('C:/Users/m/Downloads/temp01.png')

カラムの値ごとにグループ化して平均を取る

dataframe2 = dataframe2.groupby('uid', as_index=False).mean()

カラム”uid”の値ごとに平均値を求めて、グループ情報を持ったgroupby object を返す。

“as_index=True”を指定すると、”uid”がIndexになり、FalseにするとIndexは行番号になる。