Python3:CSVファイルの入出力について色々
Pandasを用いたCSVファイルの入出力について色々試してみました.下の英語ドキュメントに詳しく書いてあるんですが,自分がよく使うものだけピックアップしてメモしておきます.
テスト用にこんなCSVファイルを用意します
text1.csv ↓
hakata@hukuoka+900,100,1981 kitakyuushuu@hukuoka+900,200,1954 iiduka@hukuoka+900,300,1971
もくじ
1.読み込み編
ⅰ.普通に読み込んだ場合は一行目がheaderになる
とくに何も引数を指定しない場合は,一行目がheaderになるようです
In [1]: import pandas as pd df = pd.read_csv('text1.csv') # データフレームを作る In [2]: df Out[2]: hakata@hukuoka+900 100 1981 0 kitakyuushuu@hukuoka+900 200 1954 1 iiduka@hukuoka+900 300 1971
ⅱ.headerを無しを指定すると適当な数が埋め込まれる
引数に,header=Noneを指定すればいけます.
In [3]: df = pd.read_csv('text1.csv',header=None) In [4]: df Out[4]: 0 1 2 0 hakata@hukuoka+900 100 1981 1 kitakyuushuu@hukuoka+900 200 1954 2 iiduka@hukuoka+900 300 1971
ⅲ.headerやindexに名前をつけたい場合namesなどを使う
In [5]: df = pd.read_csv('text1.csv' ,names=('c1','c2','c3')) In [6]: df Out[6]: c1 c2 c3 0 hakata@hukuoka+900 100 1981 1 kitakyuushuu@hukuoka+900 200 1954 2 iiduka@hukuoka+900 300 1971
ⅳ.カンマ以外で区切りたいとき
たとえば"@"区切る場合はsepを使う
In [7]: df = pd.read_csv('text1.csv', header=None,sep='@') In [8]: df Out[8]: 0 1 0 hakata hukuoka+900,100,1981 1 kitakyuushuu hukuoka+900,200,1954 2 iiduka hukuoka+900,300,1971
"@"でも"+"でもカンマでも区切りたい場合はsep='[@+,]'みたいに書く
In [9]: df = pd.read_csv('text1.csv', header=None,sep='[@+,]') In [10]: df Out[10]: 0 1 2 3 4 0 hakata hukuoka 900 100 1981 1 kitakyuushuu hukuoka 900 200 1954 2 iiduka hukuoka 900 300 1971
ⅴ.特定の列をindexにしたいとき
index_col=[指定したい行]で指定するそうです.
In [11]: df = pd.read_csv('text1.csv', index_col=[0]) In [12]: df Out[12]: 100 1981 hakata@hukuoka+900 kitakyuushuu@hukuoka+900 200 1954 iiduka@hukuoka+900 300 1971
ⅵ.convertersを用いて特定の列だけ置き換える
import pandas as pd # 置き換え def sub(x): y = x.replace('@', '').replace('+900', ' ') return (y) # convertersに渡す conv = { 0: sub, # データフレーム0列目に対してsub関数を呼び出す 1: sub, # データフレーム1列目に対してsub関数を呼び出す } # データ読み込み df = pd.read_csv('testCSV1.csv', header=None,converters=conv) # 出力 print(df)
と書くと
0 1 2 0 hakatahukuoka 100 1981 1 kitakyuushuuhukuoka 200 1954 2 iidukahukuoka 300 1971
と出力される
2.書き込み編
Python3,Pandas:データフレーム検索色々
Pandasのデータフレームに格納されたデータの検索方法についていろいろ調べたり,試行錯誤したり,結局わからなかったので教えてもらいました.忘れないようにこの記事にメモしておきます.
この記事内では,共通して下記のデータフレームを用います
In [1]: import pandas as pd In [2]: df = pd.DataFrame([[1, 2, 3], [4, 5, 6], [7, 8, 9]], index=['01-01','01-02','01-03'], columns=['C1', 'C2', 'C3']) In [3]: df Out[3]: C1 C2 C3 01-01 1 2 3 01-02 4 5 6 01-03 7 8 9
1.データフレーム中のある要素が,どこの列名,どこの行名に所属するのかを出力する
まずは,Pandasのデータフレーム中のある要素が,どこの列名,どこの行名に所属するのかを獲得する方法について紹介します.
例えば,先程のデータフレームの中から要素の"3"が01-01の行,C3の列に所属する,というのを出力します.
Step.1 Multi-index化
まずは.stack() を使って先程のデータフレームをMulti-indexにします..stack()の解説は下記の通り
In [4]: s_df = df.stack() In [5]: s_df Out[5]: 01-01 C1 1 C2 2 C3 3 01-02 C1 4 C2 5 C3 6 01-03 C1 7 C2 8 C3 9 dtype: int64
Step.2 タプルから取り出し
"3"が入っているindexを取り出します.タプル形式で格納されるので,要素ごとに取り出せばOK.
In [6]: name = list(s_df[s_df == 3].index) In [7]: name[0][0] #index Out[7]: '01-01' In [8]: name[0][1] #column Out[8]: 'C3'
一発で出せるメソッドは無いんですかね??
2.Pandasのデータフレームにある値が有るか無いかを検索する
この場合は検索というより判定というのかもしれません.
データフレームに「1」と「10」がそれぞれあるのか無いのかを判定します.
In [9]: 1 in df.values Out[9]: True In [10]: 10 in df.values Out[10]: False
さいごに
ここら辺の話は何故か検索しても出てきませんでした...
教えていただきありがとうございました!
SourceTreeでPullのエラーが出たときの対処について
SourceTree (Ver 1.9.9.20)を使っていたら色々エラーが出たので,メモしておきます.
症状
こんな感じのエラーが出る
git -c diff.mnemonicprefix=false -c core.quotepath=false push -v --tags origin master:master
remote: Invalid username or password.
fatal: Authentication failed for 'https://github.com/+++/++++++.git/'Pushing to https://github.com/++++/+++++++.git
対処
これはただパスワードの設定をミスっているだけ
ツール->オプション->認証からGitHub設定する
特定の行に特定の値を代入できるか試してみる:Python3
すごい初歩的なんですが,行を指定して代入できるか試してみました.
In [22]: import numpy as np In [26]: m = np.empty((4,3)) In [27]: m Out[27]: array([[ 0., 0., 0.], [ 1., 2., 3.], [ 0., 0., 0.], [ 0., 0., 0.]]) In [28]: m[1,:] = np.array([3,3,3]) In [29]: m Out[29]: array([[ 0., 0., 0.], [ 3., 3., 3.], [ 0., 0., 0.], [ 0., 0., 0.]])
In [27]でなぜ前の値が残っているのだ??
matplotlibの超基本的な使い方:Python 3.X
matplotlibをしばらく使わないとかなり忘れてしまいます.なので使い方についてメモしておきます.
【もくじ】
まずは基本的な使い方
まずは最小構成でプロットしてみます.
最初にx軸用のデータとして,Numpyのarangeを使って-5から5まで0.2刻みの数字の列を作ります.ちなみにarangeの使い方はこちら
つぎにy軸用のデータとして,x軸用のデータを平方します.
こいつらをスクリプトで描くとこんな感じです.
import numpy as np import matplotlib.pyplot as plt # x:-5から5まで0.2刻みのデータを作る x = np.arange(-5, 5, 0.2) # y:xの値を二乗する y = x**2 # 描画 plt.plot(x, y)
このスクリプトを処理すると,,,
と見慣れた二次関数のグラフになります.
散布図を描く
つぎに散布図です.先程のスクリプトの,
# 描画
plt.plot(x, y)
のところを
# 描画 plt.plot(x, y,".")
としてあげると
みたいな点線になります
「+」の形にプロット
# 描画 plt.plot(x, y,"+")
としてあげると,+の形に点が打たれた散布図がかけます.
破線でプロット
# 描画 plt.plot(x, y,"--")
としてあげると
のような破線になります.まぁ,これは"散布図"とは呼ばないかもしれませんが・・・
画像ファイルに出力する
plt.savefig(ファイル名と形式)で画像ファイルとして出力されます.
また,pylabをインポートしてpylab.figureを呼び出せばサイズも変えられます.
一番最初のスクリプトに追記するとこんな感じです.
import numpy as np import matplotlib.pyplot as plt import pylab # ←加えた!!!サイズを変えるのに使う # x:-5から5まで0.2刻みのデータを作る x = np.arange(-5, 5, 0.2) # y:xの値を二乗する y = x**2 # サイズを変える pylab.figure(figsize=(9, 6)) #←加えた!!!!900×600のサイズになる # 描画 plt.plot(x, y) # グラフを保存 plt.savefig("image.png") #←加えた!!!!画像ファイルとして保存する
Python3,Pandas:データフレームを用いて複数のCSVファイルを連続で読み込む
1.簡単な例
最も単純な例.CSVファイルが2つを読み込んで結合する
import pandas as pd # データの読み込み f1 = pd.read_csv('CSVfile1.csv', header=None) f2 = pd.read_csv('CSVfile2.csv', header=None) # 結合 data = pd.concat([f1, f2]) # 書き出し data.to_csv('newData.csv', index=False)
2.ちょっと複雑な例
「data」というフォルダに複数のCSVファイルが格納されているとする.
これらを「glob」を使ってフォルダ全体を読み込み,データフレームに格納して結合する.
import glob import pandas as pd # ファイル読み込み files = glob.glob('data/*.csv') # ファイルを読み込んでデータフレーム作成 df = pd.concat( (pd.read_csv(f, header=None, # ファイルを読み込む.読み込む際にHeader名は無視する names=('id','val'), # Headerの名前を決める dtype={'id':'str', 'val':'str'}) # データの型を定義 for f in files)) # ファイルを連続で読み込む # 表示 print(df)
ix,loc,ilocによるデータフレームのアクセス:Pandas
ix,loc,ilocは何が違うのか?こいつらを使ってスクリプトを書いたのですが,やや気づきにくい不具合があり,苦戦しました.そんなときに下記のブログに参考にして直しましたが,自分でも試行錯誤したので,その一部を記録しておきます.
リンク先にも書いてありますが,「ちょこっと試すなら.ixを使って,長く使うなら iloc, loc が安全」かと.
列に名前がついて無い場合
ixもilocもloc同じ挙動
In [2]: import pandas as pd In [20]: df = pd.DataFrame( ...: [(10, 11, 12, 13), ...: (20, 21, 22, 23), ...: (30, 31, 32, 33)]) In [21]: df Out[21]: 0 1 2 3 0 10 11 12 13 1 20 21 22 23 2 30 31 32 33 In [22]: df.ix[1,1] Out[22]: 21 In [23]: df.loc[1,1] Out[23]: 21 In [24]: df.iloc[1,1] Out[24]: 21
列に名前(str)がついている場合
ixとilocは番号指定出来る.locは番号指定出来ない
In [7]: df = pd.DataFrame( ...: {'C1': [10, 11, 12, 13], ...: 'C2': [20, 21, 22, 23], ...: 'C3': [30, 31, 32, 33]}) In [8]: df Out[8]: C1 C2 C3 0 10 20 30 1 11 21 31 2 12 22 32 3 13 23 33 In [9]: df.ix[1,1] Out[9]: 21 In [10]: df.loc[1,1] # これはエラー In [11]: df.loc[1,'C2'] Out[11]: 21 # 列名を指定すればOK In [12]: df.iloc[1,1] Out[12]: 21
列に名前(int)がついている場合
ixだと列名の方を優先するみたいです.
In [37]: df = pd.DataFrame( ...: {5: [10, 11, 12, 13], ...: 3: [20, 21, 22, 23], ...: 1: [30, 31, 32, 33]}) In [38]: df Out[38]: 1 3 5 0 30 20 10 1 31 21 11 2 32 22 12 3 33 23 13 In [39]: df.ix[1,1] Out[39]: 31 In [40]: df.iloc[1,1] Out[40]: 21 In [41]: df.columns Out[41]: Int64Index([1, 3, 5], dtype='int64')