実行環境
- MacBook Air (11-inch, Mid 2012)
- JupyterLab (from Anaconda)
- Python 3.6.4
教材元
まえがき
pandasというライブラリーを使ってみるの回。
pandasを使うとcsv,json,xlsxファイルなどをきれいな表で表示することができる。もちろん編集もできる。
jupyterLabかjupyternotebookだときれいに表示される。anacondaには初期からプリインストールされる。
Pandas
dataframe
import pandas
a = [[1,2,3],[2,4,6]]
df1 = pandas.DataFrame(a)#1
df1 = pandas.DataFrame(a, columns=["First", "Second","Third"],index=["index0","index1"])#2
type(df1)#3
print(df1.mean())#4
print(df1.First.mean())#5
- df1をprint()すればきれいなグラフが作れる。aに二次元のリスト。a[0],a[1]がrowになる。a[0],a[1]の中身がcolumnとして振り分けられる。
- columnとrowに名前を割り振ることができる。rowの数、columnの数と同じ量指定しなければならない。データが増えるほどrowの指定は基本されない
-
pandas.core.frame.DataFrameオブジェクト - メソッドの一例。
mean()はcolumn全体の平均値を出してくれる - columnを指定してメソッドを適用させることもできる。この場合1.5が返る。(1+2)/2の計算結果
df2 = pandas.DataFrame([{"FirstName":"J"},{"LastName":"K"},{"FirstName":"Oppai"}])
- 通常じゃない方法だが、
dcit型のkeyをcolumn名として指定することもできる。keyの数だけcolumnが増える。column名は一意的なので同じ文字列かつデータ型を重複して持たない。 - 表がないので見にくいが指定されなかったrowのcolumnには
NaNのNoneが入る
csv, json, xlsxを読み込む
import pandas
# csv
df_csv = pandas.read_csv("supermarkets.csv")
# csvその2
df_csv2 = pandas.read_csv("supermarkets-semi-colons.txt",sep=";")
# json
df_json=pandas.read_json("supermarkets.json")
# xlsx
df_xlsx=pandas.read_excel("supermarkets.xlsx")
# web
df_csv3=pandas.read_csv("http://pythonhow.com/supermarkets.csv")
dir(df_csv)
import os
os.listdir()
df_csv.set_index("ID", append=True)
df_csv.shape
- csv, json, xlsxファイルを読み込むのに対応したメソッドが存在する
-
,以外で区切られたcsvファイルも読み込むことができる。sep引数を指定すればいい。 - webのurlから直接指定することもできる。
- 寄り道。
dir()メソッド内部にobjectを入れれば、インスタンス変数やメソッドを確認することができる -
os.listdir()で作業用ディレクトリーの一覧をリストの形式で取得できる。glob2ライブラリーを使いより柔軟に取得することもできる。 -
df.set_index("column_name")でグラフのrow_nameをcolumnの値に置き換えることができる。juypiterlabで動かすと一目瞭然。inplaceメソッドではない。inplace=Trueにして直接変更を加えることもできる。juypiterlabのshift+tabは神 -
shapeでDataFrameの(index数, columnの数)というintの要素を含むtupleが返される。
DataFrameの削除、追加、編集
スライス
import pandas
df = pandas.read_csv("http://pythonhow.com/supermarkets.csv")
# location
df.loc[1:3, "State":"Name]
df.loc[:2,]
# integer location
df.iloc[2:4,1:5]
df.iloc[3,4]
# column, index
df.columns
df.columns[2:5]
df.index
df.index[3:]
df.Country
df.Name
df.City
-
locは表をリストのようにスライスできる。df.loc[index範囲,column範囲]の形式。リストの実際のスライスと違って[start:end]の場合endを含んで形式で返す。 -
ilocで実際のリストと同じ感覚でスライスできる。[start:end]のendの要素はリストと同様に含まれない。 -
dir(対象のDataFrame)を使えば変数の確認ができる。df.columnsはデータフレイムのcolumnの列の各値をリストのような形式で返す(表の一番上の部分)。df.indexは上から順番にrowの要素をリストのような形式で返す。スライスできる -
df.columnsの中にあるcolumn名を使い、df.column_nameをすれば対象columnの値全てをリストのような形式で返す。スライスもできる
削除
import pandas
df = pandas.read_csv("http://pythonhow.com/supermarkets.csv")
df.drop(1, 0)
df.drop("Country",1)
-
drop()で削除できる。inplaceメソッドではないので、別の変数に格納する必要がある。1つめの引数はindexの値(intか、set_index("column_name")でkewwardが担っている場合もあるため)か、あるいはcolumn名である。2つ目の引数は0か1。0ならばrowを表す。1ならばcolumnを表す。そして指定されたrowかcolumnをまるごと削除する。 - スライスでも擬似削除ができる
追加
df["New"]="test"
df["New2"]=df["Name"]+","+df["Country"]
- "test"だとこの新しいNewのcolumnの値は、全rowで"test"になる
- 辞書のように追加できる。
df["new_column_name"]=value。list型で追加する場合は、rowの長さと同等である必要がある。 -
df["Name"]+","+df["Country"]。都合がいいことに同じrowの他のcolumnの値を取得して、値を作ることもできる。
座標
a=df["Name"][1]
b=df.Name[1]
- DataFrame、表の特定の1座標の値を取得する方法。aとbは等価である。
- aの方法の場合、`df[column_name][row_name]となる。row_nameはrowの最も左側にあるvalueを指す。グラフがないと直感的じゃない。jupyterlabで見ることを推奨。
- bの場合、
df.Nameのリストのindex[1]番目となる。 - 特定の座標に別の値を代入する場合は
df.["column_name"][row_name]=valueとすればいい。df.column_name[index]=valueでも変わる
置き換え
df_t=df.T
- rowとcolumnの位置関係を置き換えることができる。jupyterlabで確認推奨
- 新しいrowを追加したい場合は、
df.Tから前述の新しいcolumnを追加する。と同じ操作を行う。valueがリストの形式ならば、columnの種類数と同じ長さのリストである必要がある
geopy.geocodersで遊ぶ
from geopy.geocoders import Nominatim
nom = Nominatim(scheme="http")
n = nom.geocode("3395 23rd st, San Francisco, CA 94114")
print(n)
>>>Location(23rd Street, Potrero Terrace, SF, California, 94114, United States of America, (37.7544336, -122.4040117, 0.0))
type(n)
>>>geopy.location.Location
print(n.latitude)#緯度
>>>37.7544336
print(n.longitude)#経度
>>>-122.4040117
# latitude, longtitudeのカラムを作る
import pandas
df = pandas.read_csv("supermarkets.csv")
df["New_address"]=df["Address"]+","+df["City"]+","+df["State"]+","+df["Country"]
df["Coordinate"] = df["New_address"].apply(nom.geocode)
df["Latitude"]=df.Coordinates.apply(lambda x:x.latitude if x!=None else None)
df["longtitude"]=df.Coordinates.apply(lambda x:x.longtitude if x!= None else None)
- 住所を
geocode()に投げるとgeopy.location.Locationobjectを返してくれる。簡単にいうと、緯度と経度を取得できる。web接続して、対応した座標を返してくれるメソッド。 - なんか連続して実行すると、わけわかめなエラーはく。ちょっと時間おく必要ある。
pandasへ
- "New_address"というコラムを作った。値はそれぞれ同じrowから取得して、","で結合させた
-
apply()メソッドを使うと、iterateせずにrow数だけ関数を適用して、新しい値を作ることできる。"New_address"にたいして、nom.geocodeを適用した。 - "Latitude"と"Longtitude"のカラムを作る。df["Coordinates"]の各値は
geopy.location.Locationだからインスタンス変数を直接していすればいいじゃない?と思うが無理。df["Coordinates"]自体はpandas.core.series.Seriesobjectである。各rowごとにそれぞれのgeopy.location.Locationを取り出さないといけない。だからapply()を使っている。
あとがき
あそびあそばせとはたらく細胞アニメ化めでてぇ