pandasの使い方 〜列名や行名を取得する〜

csvやtsvなどの行列データを扱うのに便利なライブラリであるpandasについて解説。データフレームの列名、行名の取得方法について。

動作環境の確認(必要なライブラリインポート)

pandasをimportする必要があります。以下を実行してエラーになった場合は、適宜インストールが必要です。anacondaをインストールするのが一番楽です。

import pandas as pd

注意事項

ここではjupyter notebookを用いて解説しています。jupyter notebookとはどんなものかはJupyter事始めなどを参照。以下では"df1"と、変数だけで出力している箇所がありますが、通常のpythonでは"print (df1)"といった形でprintをつけて実行する必要があります。


本例で用いるInputFile_01.csvの中身は以下の通り。

index_col,col1,co2,col3
1/1,a,aa,aaa
1/2,b,bb,bbb
1/3,c,cc,ccc
df = pd.read_csv('inputFIle_01.csv', index_col= 0)
df
col1 co2 col3
index_col
1/1 a aa aaa
1/2 b bb bbb
1/3 c cc ccc

1. 列名を取得する場合

列名を取得したい場合、<データフレームの変数名>.columnsです。インデックスオプジェクトとして取得できます。

print df.columns
Index([u'col1', u'co2', u'col3'], dtype='object')

インデックスオブジェクトではなくリストにしたい場合は、<データフレームの変数名>.columns.valuesです。

print df.columns.values
['col1' 'co2' 'col3']

2.行名を取得する場合

行名WO取得したい場合、<データフレームの変数名>.indexです。列名と同様、インデックスオブジェクトとして取得できます。

print df.index
Index([u'1/1', u'1/2', u'1/3'], dtype='object', name=u'index_col')

リストにしたい場合、列と同様にvaluesをつけます。

print df.index.values
['1/1' '1/2' '1/3']

pandasの使い方 〜csv・tsvファイルの読み込み〜

csvやtsvなどの行列データを扱うのに便利なライブラリであるpandasについて解説。まずはデータの読み込み方法について。


動作環境の確認(必要なライブラリインポート)

pandasをimportする必要があります。以下を実行してエラーになった場合は、適宜インストールが必要です。anacondaをインストールするのが一番楽です。

import pandas as pd

注意事項

ここではjupyter notebookを用いて解説しています。jupyter notebookとはどんなものかはJupyter事始めなどを参照。以下では"df1"と、変数だけで出力している箇所がありますが、通常のpythonでは"print (df1)"といった形でprintをつけて実行する必要があります。


1. csvファイル取込の基本パターン

本例で用いるInputFile_01.csvの中身は以下の通り。

col1,col2,col3
a,b,1
aa,bb,20
aaa,bbb,3

csvファイルの取込みはpd.read_csv("ファイル名")。データフレーム型に格納した結果を返します。データフレーム型は2次元の配列とイメージは同じ。それに加え、行名、列名という概念があります。 取り込みたいファイル名だけを指定した場合、1レコード目のcol1、col2、col3が列名として使用され、行名は自動的に0から昇順に振られます。

df1 = pd.read_csv(u'InputFile_01.csv')
df1
col1 col2 col3
0 a b 1
1 aa bb 20
2 aaa bbb 3

2. ヘッダーのないcsvファイル

本例で用いるInputFile_02.csvの中身は以下の通り。

a,b,1
aa,bb,20
aaa,bbb,3

csvファイルの一行目からデータが収録されている場合(csvファイルにヘッダー、つまり列名が収録されていない場合)、header=Noneを指定します。その場合、列名は0から昇順に振られます。

df2_1 = pd.read_csv(u'InputFile_02.csv', header=None)
df2_1
0 1 2
0 a b 1
1 aa bb 20
2 aaa bbb 3

csv読み込みと同時に項目名を設定したい場合は、names=[u'項目名1', u'項目名2'・・]を指定します。

df2_2 = pd.read_csv(u'InputFile_02.csv', header=None, names=[u'col1', u'col2', u'col3'])
df2_2
col1 col2 col3
0 a b 1
1 aa bb 20
2 aaa bbb 3

3. 行名をcsvファイルのとある列から指定したい場合

本例で用いるInputFile_03.csvの中身は以下の通り。

col1,col2,col3
1,aa,aaa
2,bb,bbb
3,cc,ccc

csvの先頭列にシーケンシャルNoが付与されているなど、行名にcsvファイルのとある列を指定したい場合、index_col=<列番号>を指定します。列番号は0からカウントします。

df3 = pd.read_csv(u'InputFile_03.csv', index_col=0)
df3
col2 col3
col1
1 aa aaa
2 bb bbb
3 cc ccc

4. 先頭行をスキップして読み込みたい場合

本例で用いるInputFile_04.csvの中身は以下の通り。

2018-01-04 18:00:00
col1,col2,col3
a,aa,aaa
b,bb,bbb
c,cc,ccc

ファイルによっては一行目に制御系の情報(レコードサイズや業務日付)といった情報が収録されており、読み込みたくない場合があります。その場合はskiprows=<スキップする行数> を指定します。

df4 = pd.read_csv(u'InputFile_04.csv', skiprows=1)
df4
col1 col2 col3
0 a aa aaa
1 b bb bbb
2 c cc ccc

5. 文字コードの指定

本例で用いるInputFile_05_s-jis.csv、InputFile_05_utf8.csvの中身は以下の通り。前者の文字コードはshift-jis、後者はutf8にて記載したものです。

名前,値段
きゅうり,100
茄子,120
トマト, 60

日本語も問題なく扱えますが、文字コード(windowsだとshift-jis、Linuxmacutf-8)が違う場合はencodingオプションで指定する必要あります。オプションを指定しない場合、文字化けします。オプションはencoding = <文字コード>です。例えば、Linux環境でs-jisのファイルをオプション指定なしで開こうとした場合、以下のようになります。

df5_1 = pd.read_csv(u'InputFile_05_s-jis.csv')
df5_1
���O �l�i
0 ���イ�� 100
1 �֎q 120
2 �g�}�g 60

この場合、encoding='s-jis'を入れることで文字化けせずに読み込みできます。

df5_2 = pd.read_csv(u'InputFile_05_s-jis.csv', encoding='s-jis')
df5_2
名前 値段
0 きゅうり 100
1 茄子 120
2 トマト 60

InputFile_05_utf-8.csvutf-8のファイルです。本実行環境はLinuxなので、utf-8ならオプションがなくても文字化けしません。

df5_3 = pd.read_csv(u'InputFile_05_utf-8.csv')
df5_3
名前 値段
0 きゅうり 100
1 茄子 120
2 トマト 60

encodingですが、's-jis', 'utf_8', 'utf_8_sig'の3つを覚えていれば困ることはないかと思います。'utf_8_sig'はこれまで説明していませんでしたが、UTF-8にはBOM付きとBOM無しの2パターン有ります。BOM付きは 'utf_8_sig'、BOM無しは'utf_8'です。ここでは両者の違いの説明は割愛しますが、サクラエディタなどのエディタでひらけばどの文字コードなのかが確認できるので、それに合わせてencodingを指定します。

6. 型の指定

本例で用いるInputFile_06.csvの中身は以下の通り。

col1,col2,col3
0001,aa,0111
0002,bb,1.0
3,cc,ccc,0.01

read_csvは各列の型を自動的に判定して定義してくれます。ですが、自分が期待しない型で定義されることもあります。例えば'0001'のような値の場合、数値型とみなされ1で取り込まれます。

df6_1 = pd.read_csv(u'inputFile_06.csv')
df6_1
col1 col2 col3
0 1 aa 111.000
1 2 bb 1.000
2 3 cc 0.001

データフレーム.dtypesで各列の型が確認できます。以下のように、col1はint型、col3はfloat型で取り込まれた結果、元のcsvとは異なる文字になってしまっています。

print df6_1.dtypes
col1      int64
col2     object
col3    float64
dtype: object

型を明示的に指定したい場合、dtype = { u'項目名1' : '型名', u'項目名2' : '型名'・・}とします。主な型名は以下の通りです。

文字列 整数型 浮動小数
'object' 'int' 'float'
df6_2 = pd.read_csv(u'inputFile_06.csv', dtype = { u'col1' : 'object', u'col3' : 'object' })
df6_2
col1 col2 col3
0 0001 aa 0111
1 0002 bb 1.0
2 3 cc 0.001
print df6_2.dtypes
col1    object
col2    object
col3    object
dtype: object

意図せずデータが欠落するのを防ぐため、全項目を文字列型('object')で読み込み、あとで必要に応じて別な型に変換するといった場合、dtype = 'object'を使います。

df6_3 = pd.read_csv(u'inputFile_06.csv', dtype = 'object')
df6_3
col1 col2 col3
0 0001 aa 0111
1 0002 bb 1.0
2 3 cc 0.001
print df6_3.dtypes
col1    object
col2    object
col3    object
dtype: object

7. tsvファイルの取込み

col1 col2    col3
a   b   1
aa  bb  20
aaa bbb 3

tsvファイル(区切り文字がtab)を読み込む場合は、read_table("ファイル名")を使用します。

df7_1 = pd.read_table(u'inputFile_07.tsv')
df7_1
col1 col2 col3
0 a b 1
1 aa bb 20
2 aaa bbb 3

もしくはread_csvを使い、delimiter = '\t'(windowsだと'¥t')を指定します。delimiter =は区切り文字を自由に指定できるので、,(カンマ)やタブ以外の区切り文字にも対応できます。

df7_2 = pd.read_csv(u'inputFIle_07.tsv', delimiter='\t')
df7_2
col1 col2 col3
0 a b 1
1 aa bb 20
2 aaa bbb 3

Pythonの基本

他の言語は多少分かるけどPythonは初めて。という人向けに基本的な書き方を説明します。


1. まずは Hellow World

Python2.x系では、print ('xx')でもprint 'xx'でもOK。3.x系だとprint ('xx')のみになります。文字列は、シングルクォート、もしくはダブルクォートで括ります。

print ('Hellow World')
Hellow World
print 'Hellow World'
Hellow World
print "Hellow World"
Hellow World

2. 変数の使い方

変数の宣言(int a)は不要。数値型で扱いたい場合は、数字を変数に代入します。

a = 1
a += 1
print (a)
2

変数の型を調べたい場合はtype()を使う。

print (type(a))
<type 'int'>

文字列型の変数にしたい場合は、代入する値をシングルクォートか、ダブルクォートで括る。

b = '1'
print (type(b))
<type 'str'>

数値→文字列は、str()。文字列→数値は、int() もしくはfloat()。

print (type(a))
print (type(str(a)))
print (type(float(a)))
<type 'int'>
<type 'str'>
<type 'float'>

3. 四則演算

四則演算の記載方法は以下の通りです。

演算子 内容
* 乗算 5 * 10 = 50
/ 除算 4 / 2 = 2
+ 加算 3 + 2 = 5
- 減算 4 - 1 = 3

また、以下の演算子もあります。

演算子 内容
// 除算(小数点以下切り捨て) 5 // 2 = 2
% 剰余 5 % 3 = 2
** べき乗 3 ** 2 = 27
print (5 * 10)
50
print (4 / 2)
2
print (5 / 2)
2
print (5 // 2)
2
print (5 % 3) 
2
print (5 ** 2)
25

4. 文字列+数値型の変数を組み合わせたprint

name = 'test'
allcount = 10
count = 1
print (type(name))
print(type(allcount))
print (type(count))
<type 'str'>
<type 'int'>
<type 'int'>

一番便利なのが、format()。文章中、変数を表示させたい場所に{数字}を書き、format()のカッコ内に対応する変数を記述していきます。数字は0から昇順に採番。変数がどの型かを意識する必要はないです。

print ('プログラム名{0}:全{1}回目中、{2}回目の処理です'.format(name, allcount, count))
プログラム名test:全10回目中、1回目の処理です

数値の変数を見栄え良く、001、002・・と、頭0補填したい時があるかと思います。その場合は、{数字:書式}とすれば良いです。例えば、2桁に満たない場合は頭0補填する。という場合の書式は'02d'です。

print ('プログラム名{0}:全{1:03d}回目中、{2:02d}回目の処理です'.format(name, allcount, count))
プログラム名test:全010回目中、01回目の処理です

他の方法としては、全ての変数を文字列に変換した上で、文字列 + 文字列 で文字連結したものをprintする方法もあります。

print('プログラム名' + name + ':全' +  str(allcount) + '回目中、' + str(count) + '回目の処理です')
プログラム名test:全10回目中、1回目の処理です

zfill()で頭0埋めも可能です。

print('プログラム名' + name + ':全' +  str(allcount).zfill(3) + '回目中、' + str(count).zfill(2) + '回目の処理です')
プログラム名test:全010回目中、01回目の処理です

format()の方が型を意識しなくて済む上、可読性もformat()方式の方が優れていると思うので、format()オススメ。

5. if文の書き方

if文は以下の通り。

if  条件式:  
    処理内容  
elif 条件式:  
    処理内容  
elif 条件式:  
    処理内容  
else:  
    処理内容  

条件式の最後にコロン(:)を忘れがちなので注意。また、if文やfor文など、どこまでの行を処理内容とするかはインデントにて制御します。
例えば、

if 条件式:    
    処理内容1  
    処理内容2  
処理内容3  

と書いた場合、ifの条件式に合致した場合にのみ実行されるのは処理内容1と処理内容2だけです。逆に処理内容3はifの条件に合致するorしないに関わらず実行される処理になります。 インデントはスペースでもタブでも良いですが、統一する必要があります。ちなみに、python推奨はスペース4つです。

条件式で使用する比較演算子は以下の通り。

演算子 記述例 意味
== a == b aとbが等しい
!= a != b aとbが等しくない
> a > b aがbより大きい
>= a >= b aがb以上
< a < b bがaより大きい
=< a <= b bがa以上

複数の条件式を記述したい場合に使用する論理演算子は以下の通り。

演算子 記述例 意味
and a and b aかつbが真の時、真
or a or b aまたはbが真の時、真
not not a aが偽の時、真
a = 100

if a == 100:
    print ("yes")
else:
    print("no")
yes
a = 100
b = 50

if a == 100 and b == 100:
    print('case1')
elif a == 100 and b == 50:
    print('case2')
else:
    print('error')
case2
a = 100
b = 50

if a == 100 and b != 50:
    print('case1')
elif a != 100 or b == 100:
    print('case2')
else:
    print('error')
error

6. 繰り返し文の書き方

6-1. for文の書き方

for文の書き方は以下の通り。

for 変数 in オブジェクト:
  実行する処理1
  実行する処理2

if文同様、オブジェクトの後にコロン(:)をつける点、繰り返し対象の処理はインデントをずらす(スペースでもタブでも良いが統一する)点がポイントです。処理イメージは、リスト型や文字列などのシーケンシャルなオブジェクトの要素を先頭から順に変数iに渡し、実行する処理を行う。というものです。ちょっとわかりづらいので、実際に試してみましょう。

list = ['test1','test2','test3','test4']
for i in list:
    print (i)
test1
test2
test3
test4
name = 'Hellow World'
for i in name:
    print ('get : {0}'.format(i))
get : H
get : e
get : l
get : l
get : o
get : w
get :  
get : W
get : o
get : r
get : l
get : d

10回繰り返したいだけなのに、わざわざlist用意するのめんどくさいな・・という時は、range()を使いましょう。

for i in range(10):
    print (i)
0
1
2
3
4
5
6
7
8
9

「for 変数 in オブジェクト:」という書き方はちょっと特殊なので最初は戸惑いますが、だんだん便利に感じてくると思います。リスト分だけ繰り返し何かの処理を行う。ということが思ったより多いので、そういう場合、すごく直接的に書けます。

6-2. while文の書き方

while文の書き方は以下の通りです。

while 条件式:
    処理内容1
    処理内容2

条件式の最後にコロン(:)を記述する点、繰り返し対象の処理は、インデントをずらす(スペース、タブどれでも良いが統一する)以外は特に注意点はありません。

i = 0
while i <= 3:
    print (i)
    i += 1
0
1
2
3

pythonの基本的な書き方は以上です。

PythonやAIなどのアレコレを書いていこうと思います

金融系の職場でSEとして大量かつ様々なフォーマット(CSV, EXCEL, JSON・・)のデータを加工したり、テストしたりしています。また、個人的にAIとかブロックチェーンとかも勉強したり。勉強したそれらをアウトプットしていきたいと思います。