Python Coding Reference — 4-1. pandas(DataFrame) —

初期化

import pandas as pd

空のDataFrameを作成

df = pd.DataFrame()
==> Empty DataFrame
==> Columns: []
==> Index: []

初期値を持ったDataFrameを作成

df = pd.DataFrame([['a', 'b', 'c'], [10,20,30]])
==>     0   1   2
==> 0   a   b   c
==> 1  10  20  30

列名と初期値を持ったDataFrameを作成

df = pd.DataFrame([['a', 10], ['b', 20], ['c', 30]], columns=['key', 'val'])
==>   key  val
==> 0   a   10
==> 1   b   20
==> 2   c   30

CSVファイル読込み

※ファイル名=dataframe_csv_test.csv

Data(dataframe_csv_test.csv)

key,val,col1,col2
1,TESTa,テスト1,テスト01
2,TESTb,テスト2,テスト02
3,TESTc,テスト3,テスト03

UTF-8(標準)

df = pd.read_csv('dataframe_csv_test.csv', encoding='utf-8')
==>    key    val  col1   col2
==> 0    1  TESTa  テスト1  テスト01
==> 1    2  TESTb  テスト2  テスト02
==> 2    3  TESTc  テスト3  テスト03

文字コードがShiftJIS(CP932)の場合

df = pd.read_csv('dataframe_csv_test.csv', encoding='cp932')
==> UnicodeDecodeError: 'cp932' codec can't decode byte 0x86 in position 2: illegal multibyte sequence
※UTF-8マルチバイトを含むファイルを読込むと、上記エラーとなる。
 
df = pd.read_csv('dataframe_csv_test_cp932.csv', encoding='cp932')
==>    key    val  col1   col2
==> 0    1  TESTa  テスト1  テスト01
==> 1    2  TESTb  テスト2  テスト02
==> 2    3  TESTc  テスト3  テスト03

ヘッダ行を列名扱いしない場合

df = pd.read_csv('dataframe_csv_test.csv', header=None)
==> 0  key    val  col1   col2
==> 1    1  TESTa  テスト1  テスト01
==> 2    2  TESTb  テスト2  テスト02
==> 3    3  TESTc  テスト3  テスト03
※列名もデータ扱いされる。

ヘッダを読み飛ばしたいとき

df = pd.read_csv('dataframe_csv_test.csv', header=None, skiprows=1)
==>    0      1     2      3
==> 0  1  TESTa  テスト1  テスト01
==> 1  2  TESTb  テスト2  テスト02
==> 2  3  TESTc  テスト3  テスト03
※ pd.read_csv('dataframe_csv_test.csv', header=None, skiprows=[0]) でも同じ
  skiprowsのリスト指定は、INDEX番号で任意の行をスキップできる

先頭の2行のみ読込む場合

df = pd.read_csv('dataframe_csv_test.csv', nrows=2)
==>    key    val  col1   col2
==> 0    1  TESTa  テスト1  テスト01
==> 1    2  TESTb  テスト2  テスト02

CSVファイル出力

df = pd.read_csv('dataframe_csv_test.csv', encoding='utf-8')
df.to_csv('dataframe_out_test.csv')

Data(dataframe_csv_test.csv)

,key,val,col1,col2
0,1,TESTa,テスト1,テスト01
1,2,TESTb,テスト2,テスト02
2,3,TESTc,テスト3,テスト03

Excelファイル読込み

df = pd.read_excel('dataframe_xls_test.xlsx', sheet_name='dataframe_test')
==>    key    val  col1     col2
==> 0   10  TESTA  テスト1  テスト10
==> 1   20  TESTB  テスト2  テスト20
==> 2   30  TESTC  テスト3  テスト30

HTMLファイルの読込み

df = pd.read_html('dataframe_html_test.html', encoding='utf-8')  # utf-8
==> [     0       1     2       3
==> 0  key     val  col1    col2
==> 1   10  TEST-A  テスト1  テスト100
==> 2   20  TEST-B  テスト2  テスト200
==> 3   30  TEST-C  テスト3  テスト300]
 
※結果はリストとして戻され、その中の一要素としてDataFrameが含まれている形となる
==> >>> print(type(df))
==> <class 'list'>
==> >>> print(type(df[0]))
==> <class 'pandas.core.frame.DataFrame'>

列名の設定

列名はcolumns

df = pd.read_csv('dataframe_csv_test.csv', encoding='utf-8')
==>    key    val  col1   col2
==> 0    1  TESTa  テスト1  テスト01
==> 1    2  TESTb  テスト2  テスト02
==> 2    3  TESTc  テスト3  テスト03
 
print(df.columns)
==> Index(['key', 'val', 'col1', 'col2'], dtype='object')
 
df.columns = ["キー","値","列1","列2"]
print(df.columns)
==> Index(['キー', '値', '列1', '列2'], dtype='object')

行名の設定

行名はindex

df = pd.read_csv('dataframe_csv_test.csv', encoding='utf-8')
print(df.index)
 
==> RangeIndex(start=0, stop=3, step=1)
df.index = ["a","b","c"]
 
print(df)
==>    キー      値    列1     列2
==> a   1  TESTa  テスト1  テスト01
==> b   2  TESTb  テスト2  テスト02
==> c   3  TESTc  テスト3  テスト03
 
print(df.index)
Index(['a', 'b', 'c'], dtype='object')

データの一部取得(head/tail)

先頭5行取得

df = pd.DataFrame([['a', 10], ['b', 20], ['c', 30], ['d', 40], ['e', 50], ['f', 60]], columns=['key', 'val'])
df.head()
==>   key  val
==> 0   a   10
==> 1   b   20
==> 2   c   30
==> 3   d   40
==> 4   e   50

先頭2行取得

df.head(2)
==>   key  val
==>   key  val
==> 0   a   10
==> 1   b   20

末尾5行取得

df.tail()
==>   key  val
==> 1   b   20
==> 2   c   30
==> 3   d   40
==> 4   e   50
==> 5   f   60

欠損値の扱い

欠損値の有無チェック 行列毎にNaNならTrue/False

df = pd.DataFrame([['a', 10], ['b', 20], ['c', None], [None, 40], ['e', 50]], columns=['key', 'val'])
df.isnull()
==>      key    val
==> 0  False  False
==> 1  False  False
==> 2  False   True
==> 3   True  False
==> 4  False  False

欠損値の有無チェック 行列毎にnotNaNならTrue/False

df.notnull()
==>      key    val
==> 0   True   True
==> 1   True   True
==> 2   True  False
==> 3  False   True
==> 4   True   True

列毎の欠損値の数をカウント

df.isnull().sum()
==> key    1
==> val    1
==> dtype: int64

行毎の欠損値の数をカウント

df.isnull().sum(axis=1)
==> 0    0
==> 1    0
==> 2    1
==> 3    1
==> 4    0
==> dtype: int64

欠損値の削除(欠損値を含む行を削除)

df.dropna()
==>   key   val
==> 0   a  10.0
==> 1   b  20.0
==> 4   e  50.0
※破壊的な削除は行われない。df自体から削除したいときは、inplace=Trueを指定する
 
※3列あって、Noneを含まない行が1行のみ存在する場合
df = pd.DataFrame([['a', 10, 1], ['b', 20, None], ['c', None, 3], [None, 40, 4]], columns=['key', 'val', 'desc'])
df.dropna(axis=0)
==>   key   val  desc
==> 0   a  10.0   1.0

欠損値の削除(欠損値を含む列を削除)

※2列あって、双方にNoneを含む行が存在する場合
df = pd.DataFrame([['a', 10], ['b', 20], ['c', None], [None, 40]], columns=['key', 'val'])
 
df.dropna(axis=1)
==> Empty DataFrame
==> Columns: []
==> Index: [0, 1, 2, 3]
※2列とも削除されるので、Empty DataFrameが戻される
 
※3列あって、最終列のみ欠損値を含まない場合
df = pd.DataFrame([['a', 10, 1], ['b', 20, 1], ['c', None, 3], [None, 40, 4]], columns=['key', 'val', 'desc'])
df.dropna(axis=1)
==>    desc
==> 0     1
==> 1     1
==> 2     3
==> 3     4

全ての要素が欠損値の行を削除(how)

df = pd.DataFrame([['a', 10, 1], [None, None, None], ['c', None, 1], [None, 40, 1]], columns=['key', 'val', 'desc'])
df.dropna(how='all')
==>     key   val  desc
==> 0     a  10.0   1.0
==> 2     c   NaN   1.0
==> 3  None  40.0   1.0

全ての要素が欠損値の行を削除(thresh)

df.dropna(thresh=1)
==>     key   val  desc
==> 0     a  10.0   1.0
==> 2     c   NaN   1.0
==> 3  None  40.0   1.0
※thresh=1の場合、1個未満の場合に削除。2個以上ある場合は削除しない。

“val"列に欠損値がある行を削除(subset)

df = pd.DataFrame([['a', 10, 1], ['b', 20, 1], ['c', None, 3], [None, 40, 4]], columns=['key', 'val', 'desc'])
df.dropna(subset=['val'])
==>     key   val  desc
==> 0     a  10.0     1
==> 1     b  20.0     1
==> 3  None  40.0     4

欠損値を0で埋める

df.fillna(0)
==>   key   val  desc
==> 0   a  10.0     1
==> 1   b  20.0     1
==> 2   c   0.0     3
==> 3   0  40.0     4

欠損値を一つ前の値で埋める

df.fillna(method='ffill')
==>   key   val  desc
==> 0   a  10.0   1.0
==> 1   a  10.0   1.0
==> 2   c  10.0   1.0
==> 3   c  40.0   1.0

欠損値を平均値(mean)で埋める

df.fillna(df.mean())
==>     key        val  desc
==> 0     a  10.000000     1
==> 1     b  20.000000     1
==> 2     c  23.333333     3
==> 3  None  40.000000     4

欠損値を中央値(median)で埋める

df.fillna(df.median())
==>     key   val  desc
==> 0     a  10.0     1
==> 1     b  20.0     1
==> 2     c  20.0     3
==> 3  None  40.0     4

欠損値を最頻値で埋める

※ modeで頻度のランキングを算出。iloc[0]で先頭行のみ取得

df.fillna(df.mode().iloc[0])
==>   key   val  desc
==> 0   a  10.0     1
==> 1   b  20.0     1
==> 2   c  10.0     3
==> 3   a  40.0     4

2021-09-21

Posted by tfurukaw