実行環境
- 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.Location
objectを返してくれる。簡単にいうと、緯度と経度を取得できる。web接続して、対応した座標を返してくれるメソッド。 - なんか連続して実行すると、わけわかめなエラーはく。ちょっと時間おく必要ある。
pandasへ
1. "New_address"というコラムを作った。値はそれぞれ同じrowから取得して、","で結合させた
2. apply()
メソッドを使うと、iterateせずにrow数だけ関数を適用して、新しい値を作ることできる。"New_address"にたいして、nom.geocode
を適用した。
3. "Latitude"と"Longtitude"のカラムを作る。df["Coordinates"]の各値はgeopy.location.Location
だからインスタンス変数を直接していすればいいじゃない?と思うが無理。df["Coordinates"]自体はpandas.core.series.Series
objectである。各rowごとにそれぞれのgeopy.location.Location
を取り出さないといけない。だからapply()
を使っている。
あとがき
あそびあそばせとはたらく細胞アニメ化めでてぇ