LoginSignup
6
9

More than 1 year has passed since last update.

Pandas Tips -よく使うコードリスト(文例集)-

Last updated at Posted at 2021-02-07

Pythonをときどき使う自分は、コードの細かい書き方をすぐに忘れてしまい、毎回同じサイトや本を見たりすることになります。内容は何度も見て知っているので、書き方だけをちょっと思い出したい、という場面がしょっちゅうあります。そんなときに、よく使うコードの文例が1ページにまとまっているサイトがあると便利かなと思います。
そんな目的で、今回はPandasについて、自分が良く使うコードの部品を以下に書いていきます。
解説については、冒頭に挙げた参考ページを見ていただければと思います。また、各項目にもリンクを貼ってあります。項目ごとのリンク集としても使えるかなと思います。

随時更新していきます。

動作確認:Python 3.7.9、Pandas 1.1.2

よく参考にするページ

基本操作

import numpy as np  # numpyのimport
import pandas as pd  # pandasのimport
pd.__version__  # バージョン確認

データフレームの作成(1)

  • データフレームを新規作成する。
# パターン1
cols = ['A', 'B', 'C', 'D']  # columns=list('ABCD')でもよい
a = np.random.randn(5,4)
df = pd.DataFrame(a, columns=cols)

# パターン2 : 空のデータフレームを作って、後からデータ(行)を追加(よく使う)
cols = ['A', 'B', 'C', 'D']
df = pd.DataFrame(index=[], columns=cols)
dfa = pd.DataFrame(np.random.randn(5,4), columns=cols)
df = df.append(dfa).reset_index(drop=True)

# パターン3 : リストからデータフレームを作成
# 1行4列
cols = ['A', 'B', 'C', 'D']
list = [[1, 2, 3, 4]]
df = pd.DataFrame(list, columns=cols)
# 4行1列
cols = ['A']
list = [1, 2, 3, 4]
df = pd.DataFrame(list, columns=cols)

# データフレームのリストの作成
df = pd.DataFrame(np.random.randn(10, 4))
pieces = [df[:3], df[3:7], df[7:]]

データフレームの作成(2) Numpyの配列から

  • Numpyの配列からデータフレームを新規作成する。
cols = ['x', 'y', 'z']
a = np.random.randn(10,2)
b = np.linspace(0, 1, 10)[:,np.newaxis] # newaxisを用いて行ベクトルの作成
c = np.hstack([a,b]) # 配列の水平方向への結合
df = pd.DataFrame(c, columns=cols)

CSVファイルの読み込み、書き出し

filename = 'data.csv'
df = pd.read_csv(filename) # 何も指定しないと1行目がheaderとして認識され、列名columnsに割り当てられる。
df = pd.read_csv(filename, header=None) # header=Noneとすると連番[0,1,…]が列名columnsに割り当てられる。
df = pd.read_csv(filename, names=list('ABCD')) # 任意の値[names]を列名として設定
df = pd.read_csv(filename, header=2) # headerで指定した行からデータが読み込まれ、それより上の行は無視される。
df = pd.read_csv(filename, index_col=0) # index_col=0のようにindexとして使いたい列の列番号を0始まりで指定する。
                                       # 環境によってはWarningが出るので、下記のように引数engine='python'を指定する。
df = pd.read_csv(filename, skiprows=2, skipfooter=1, engine='python') # スキップする行数を指定(初めと終わり)
df = pd.read_csv(filename, nrows=1) # 行数を指定
df = pd.read_csv(filename, sep=',') # 区切り文字を指定(コンマ)、その他 スペースやタブ区切りの場合は、sep=' ', sep='\t'
df.to_csv('data.csv')
df.to_csv('data.csv', header=False, index=False) #ヘッダー、カラムなし
df.to_csv('data.csv', header=False, index=False, encoding='utf-8') # python3は'utf-8がデフォルト 
df.to_csv('data.csv', header=False, index=False, encoding='shift_jis') # 日本語を含むファイルをエクセルなどで使う場合
df.to_csv('data.csv', float_format='%10.3f') #フォーマットを指定
df.to_csv('data.tsv', sep='\t') # タブ区切り
filename = 'data.txt' #8F10.3のデータ形式の場合 
colspecs = [(0,10),(11,20),(21,30),(31,40),(41,50),(51,60),(61,70),(71,80)]
df = pd.read_fwf(filename, skiprows=1, header=None, colspecs=colspecs)

その他データの読み込み、書き出し

  • クリップボードのデータの読み込み、書き出しは、エクセルからのデータをデータフレームにしたり、データフレームのデータをエクセルに貼りつけたりするときに便利!
df = pd.read_clipboard() #クリップボードからのデータの読み込み
df = pd.read_clipboard(sep=',') # 区切り文字を指定する場合

df.to_clipboard() #クリップボードへのデータの書き込み
df.to_clipboard(sep=',')  #区切り文字を指定する場合

データの表示・確認

  • データの内容を表示、確認する。
## データの表示、確認
df.describe  # データのサマリー
df.head()  # データの初めの部分
df.tail()  # データの終わりの部分
df.index  # インデックス
df.columns  # カラム

データ型の指定、変換

## データの型を表示
s.dtype  #Seriesの場合
df.dtypes #Dataflameの場合
## データの型を指定
s = pd.Series([0, 1, 2], dtype='float64') # 倍精度浮動小数点型
s = pd.Series([0, 1, 2], dtype='int64') # 符号あり64ビット整数型

## データの型を変換
# Seriesの場合
s_f = s.astype('float64') 

# Dataflemeの場合
cols = ['A', 'B', 'C', 'D'] 
a = [[11, 12, 13, 14],[21, 22, 23, 24]] 
df = pd.DataFrame(a, columns=cols, dtype='int64')

df_f = df.astype('float64') #一括変換
df_f = df.astype({'A':'float64'}) #任意の1列
df_f = df.astype({'A':'float64'}, {'C':'str'}) #任意の複数列

データの選択

## データの選択
df['A'] #カラム名による列の選択
df.A  # 同上
df[['A','C']] #複数カラムの場合

df[0:3] #インデックス番号による行の選択

# .locによる行と列の選択(ラベルを使用)
df.loc[:,['A','B']] # 複数列の選択
df.loc[0:2,['A','B']] # 複数列、複数行の選択

# .ilocによる行と列の選択(インデックス番号、カラム番号を使用)
df.iloc[2] # インデックスNoを指定して行を選択 
df.iloc[1:3,:2] # インデックスNo、カラムNoを指定して行、列を選択

df[df['A'] > 0] # 特定の条件を指定しての行、列の選択

データの結合

# サンプルの作成
df1 = pd.DataFrame({'A': ['A1', 'A2', 'A3'],
                   'B': ['B1', 'B2', 'B3'],
                   'C': ['C1', 'C2', 'C3']},
                  index=['ONE', 'TWO', 'THREE'])
df2 = pd.DataFrame({'C': ['C2', 'C3', 'C4'],
                   'D': ['D2', 'D3', 'D4']},
                  index=['TWO', 'THREE', 'FOUR'])

# Concatを使う場合
pd.concat([df1, df2]) # 結合するデータフレームをリストやタプルで指定
pd.concat([df1, df2, df1]) # 3つ以上でもOK
pd.concat([df1, df2], axis=0) # 縦方向に連結(デフォルト)
pd.concat([df1, df2], axis=1) # 横方向に連結
pd.concat([df1, df2], join='outer') #外部結合(全ての列(または行)が残る)
pd.concat([df1, df2], join='inner') #外部結合(共通の列(または行)のみが残る)

# appendを使う場合
df1.append(df2) #df1にdf2を縦方向に連結
df1.append([df1, df2]) #リストやタプルで複数も可

データの抽出(queryを中心に)

# サンプルの作成
df1 = pd.DataFrame({'A': range(1, 6),
                  'BB': range(10, 0, -2),
                  'C C': range(10, 5, -1)})

df2 = pd.DataFrame({'A': ['A1', 'D2', 'H3'],
                   'B': ['AB1', 'BC2', 'CD3'],
                   'C': ['ABC1', 'BBC2', 'CBC3']},
                  index=['ONE', 'TWO', 'THREE'])

# シンプルな書き方
df1[df1.A > df1.BB]
df1[df1.BB == df1['C C']]

# queryを使う場合
df1.query('A > BB')
df1.query('BB == `C C`') #文字列にスペースを含む場合は、バッククォートで囲う
df1.query('BB != `C C`')
df1.query('A > BB & A > 9') # A>BB かつ A>9
df1.query('A > BB | A >= 5') # A>BB または A>=5
a = 5
df1.query('A > BB | A >= {}'.format(a)) # A>BB または A>=5(変数を使う場合)

df2.query('B.str.startswith("A")', engine='python') #B列が文字列Aで始まる行
df2.query('B.str.endswith("2")', engine='python') #B列が文字列2で終わる行
df2.query('C.str.contains("CBC")', engine='python') #C列が文字列CBCを含む行
df2.query('A.str.contains("^[D-J]", regex=True)', engine='python') #A列がアルファベットのD~Jのいずれかを含む行
df2.query('A.str.contains("^[B-H].*[2-9]$", regex=True)', engine='python') #A列の先頭がアルファベットのB~Hではじまり、末尾が数字の3~9で終わる行

時系列データ

# 基本
import datetime  # 日付と時刻を扱うためのpythonの基本オブジェクト

start = datetime.datetime(2011, 1, 1)
end = datetime.datetime(2012, 1, 1)

index = pd.date_range(start, end) 
index = pd.date_range(start, end, freq='D') # D:日次
index = pd.date_range(start, end, freq='H') # H:毎時、T:毎分、S:毎秒
index = pd.date_range(start, periods=1000, freq="M") # M:月末ごと、MS:毎月初
index = pd.date_range(start, periods=1000, freq="W") # W:週次

index = pd.period_range("2018-04", "2020-12", freq='M') # 月ごと
index.days_in_month #月の日数を取得
  • 時間によるインデックスと抽出
dft1 = pd.DataFrame(
   np.random.randn(100000, 1),
   columns=["A"],
   index=pd.date_range("20130101", periods=100000, freq="T"),)

dft1.loc["2013"] # 2013年を抽出
dft1.loc["2013-1":"2013-2"] # 期間を指定して抽出(その1)
dft1.loc["2013-1-15":"2013-1-15 12:30:00"] # 期間を指定して抽出(その2)
dft2 = pd.DataFrame({'A': ['2017-11-01 12:24', '2017-11-18 23:00', '2017-11-18 23:00'],
                   'B': ['2017年11月1日 12時24分', '2017年11月18日 23時00分', '2017年12月5日 5時05分']})
print(dft2.dtypes, type(dft2['A'][0])) #いずれの列もobject型(各要素は文字列str型)

dft2['A'] = pd.to_datetime(dft2['A']) # datetime64[ns]型への変換
dft2['B'] = pd.to_datetime(dft2['B'], format='%Y年%m月%d日 %H時%M分') # フォーマットの指定

欠損値の扱い

# 欠損値を削除
df.dropna(how='all') # すべての値が欠損値NaNである行を削除
df.dropna((how='all', axis=1)) # 列の場合
df2.dropna(how='any') # 欠損値が一つでも含まれる行を削除

# 欠損値を置換、穴埋め
df.fillna(0) # 欠損値NaNを共通の値で一律に置換(この場合は0で置換) もとのオブジェクトは変更されないことに注意!
df.fillna(0, inplace=True)  # もとのオブジェクトを変更
df.fillna(method='ffill') # 前(上)の値で置換
df.fillna(method='bfill') # 後ろ(下)の値で置換

以下、更新中

6
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
9