Pandas 特定の文字列取得
1 2 3 4 5 6 7 8 9 10 11 12 13 | lst = [ "近隣10分20000円" , "近隣5分5000円" , "敷地内25000円" ,""] df = pd.DataFrame(lst, columns = [ '駐車場' ]) import re def fee(x): m = re.search(r '\d+円' , x) if m: return m.group() else : return "" df[ '駐車料金' ] = df[ '駐車場' ]. apply (fee) print (df) |
これは apply を使うとできる
「駐車場」列から、金額のみを抽出して、新たな列「駐車料金」
として追加
これだと円が入っているので
これを金額のみにする
re.search() で正規表現で探れる
[解決!Python]re.search/re.match関数と正規表現を使って文字列から部分文字列を抽出するには
を参考に
1 2 3 4 5 6 7 | s = 'id: deep, mail: deep@foo.com, tel: 03-0123-4567' # re.search関数は文字列にパターンとマッチする部分があるかを調べる m = re.search( 'tel: [-\d]+' , s) print (m) # <re.Match object; span=(30, 47), match='tel: 03-0123-4567'> r = m.group() # re.Matchオブジェクトのgroupメソッドでマッチ全体を抽出 print (r) # tel: 03-0123-4567 |
つまり
1 2 3 | def fee(x): m = re.search(r '\d+円' , x) |
の部分で
xとして渡された文字列から
1 | '\d+円' |
で検索している
re.search(r’
で検索したら
正規表現の先頭につく`r`は何ですか?エスケープシーケンスやrow文字列を解説します
とのこと
正規表現を使う時に
R をつけることを推奨しているためらしい
次にわからんのが
m.group()
マッチした文字列を取得: group()
とあった
Pythonの正規表現マッチオブジェクトでマッチした文字列や位置を取得
を参考に
つまり
1 2 3 4 | m = re.search(r '\d+円' , x) if m: return m.group() |
の部分で
1 | \d + 円 |
にマッチする部分を格納している
次に
1 | df[ '駐車料金' ] = df[ '駐車場' ]. apply (fee) |
の部分
pandasのapply関数の代表的な使い方
が参考になる
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | df = pd.DataFrame({ "col_A" : [ 100 , 300 , 200 , 400 , 200 , 700 , 200 ], "col_B" : [ "A" , "B" , "C" , "D" , "E" , "D" , "C" ], "col_C" : [ 2 , 3 , 5 , 1 , 2 , 3 , 8 ] }) df.head( 10 ) # 受け取ったレコードに対して、やりたい操作を記述する def func1(row): return row[ "col_A" ] * row[ "col_C" ] # dfをレコード単位でfunc1に渡して何らかの操作をしてもらう。戻り値は新たに作成する"col_D"に保存する。 df[ "col_D" ] = df. apply (func1, axis = 1 ) df.head( 10 ) # 受け取った値に対して、やりたい操作を記述する def func2(x): return x * 100 # dfの"col_D"の値をfunc2に渡して何らかの操作をしてもらう。戻り値は新たに作成する"col_E"に保存する。 df[ "col_E" ] = df[ "col_D" ]. apply (func2) df |
でみるとわかるけど
Def で定義した自作メソッドを
apply() で実行している
そして新しいカラムを追加して
そこへ処理した結果を格納している
とりあえず
まずは apply などで
円の文字を削除してみよう
これができればツイートから経済指標部分を「取り出し
数値以外を削除して数値を文字列に変換すれば処理できる
Pandasで不要な文字を取り除いたり置換する方法まとめ
https://deepage.net/features/pandas-str-replace.html#%E7%89%B9%E5%AE%9A%E3%81%AE%E6%96%87%E5%AD%97%E3%82%92%E6%8C%87%E5%AE%9A%E3%81%97%E3%81%A6%E6%B6%88%E5%8E%BB
を参考に
1 | str .strip() |
で削除できる
今回は円を削除したい
1 | df[ '駐車料金' ]. str .strip( '円.' ) |
で削除はできる
あとは反映
1 2 3 | df[ '駐車料金' ] = df[ '駐車料金' ]. str .strip( '円.' ) df |
と経済指標のときみたいに代入すればok
これで文字列の編集はできるので
次に pandas で特定の文字を含む行の抽出をする
まずはツイートの取得と変数への格納
その前に経済指標カレンダーの取得
これがあっているか調べないとだめ
1 2 3 4 5 6 7 8 | import pandas as pd dfs = pd.read_html(url)[ 0 ] #テーブルのオブジェクトを生成 #本日のカレンダーを取得 dfs |
でも十分に使える
余分なものをなくしてみやすくするなら
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | import pandas as pd dfs = pd.read_html(url) #テーブルのオブジェクトを生成 #前処理開始 dfs1 = dfs[ 0 ].dropna(subset = [ 4 ]) #4番にNaNが入っている行はバグなので、削除 dfs2 = dfs1.drop( 2 ,axis = 1 ) #2番目の列を削除。axis = 1は列を削除するオプション dfs2.columns = [ "発表時間" , "経済指標" , "前回変動幅(USD/JPY)" , "前回" , "予想" , "結果" ] #列名を手動で追加。 #前処理終了 dfs2 #テーブルを表示 |
となる
よくみたら配列で0〜6で
0が月曜
つまりdatetime などで曜日を取得してしていする必要がある
引数に曜日を数値で指定する必要ですかあるが
https://itips.krsw.biz/python-get-week-number/#st-toc-h-4
にあるように
Pythonで曜日を数字で取得する方法 まとめ
Pythonで曜日を取得するには weekday() を使う。
weekday() は今日(today)以外にもdatetime型の変数にも適用可能。
戻り値は0から6までの数値で月曜日が0に当たる。
とのこと
つまり今日の日付を取得して
これを使えば曜日指定できるはず
1 2 3 4 5 6 7 8 9 10 11 12 13 | import datetime # 曜日番号を取得(0は月曜日) week_num = datetime.date.today().weekday() print (datetime.date.today()) print ( type (datetime.date.today())) print (week_num) |
このweek_num を使えば指定できるはず
これは成功
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | import pandas as pd import datetime week_num = datetime.date.today().weekday() dfs = pd.read_html(url) #テーブルのオブジェクトを生成 print (week_num) で曜日の数値が出る |
あとは
1 | dfs[week_num] |
で本日のカレンダーを取得できる
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | import pandas as pd dfs = pd.read_html(url) #テーブルのオブジェクトを生成 #前処理開始 dfs1 = dfs[ 0 ].dropna(subset = [week_num]) #4番にNaNが入っている行はバグなので、削除 dfs2 = dfs1.drop( 2 ,axis = 1 ) #2番目の列を削除。axis = 1は列を削除するオプション dfs2.columns = [ "発表時間" , "経済指標" , "前回変動幅(USD/JPY)" , "前回" , "予想" , "結果" ] #列名を手動で追加。 #前処理終了 dfs2 #テーブルを表示 |
をそのあとで実行するとよりわかりやすく表示できる
そのまま経済指標のカレンダーで
Twitter で検索しても出ないが
予測値などを取得することはできるはず
次は
Pandas で時刻の比較とかトリガーとして使う方法を探す
これは
Pandas】DataFrameの文字列日付データを比較して、抽出したりする
https://www.tcom242242.net/entry/python-basic/dataframe-date-compare-extract/#toc7
を参考にまず日時の部分をdatetime へ変換する
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #Dfs2 の発表時間をdatetime へ変換 def convert_date(x): date = datetime.datetime.strptime(x, "%Y-%m-%d %H:%M:%S" ) return date dfs2[ "発表時間" ] = dfs2[ "発表時間" ]. apply (convert_date) dfs2 |
だとエラー
https://qiita.com/over_di/items/1270d3737e0a81719e56
Applyだとエラーになる
Pandas の to_datetime()
だとできるけど
年数の指定がないため1900年1月1日になってしまう
これを解決しないとだめ
これを解決するには
https://qiita.com/over_di/items/1270d3737e0a81719e56
Pandasのpd.to_datetimeで時刻のみ抜き出す方法
を参考に
https://qiita.com/over_di/items/1270d3737e0a81719e56
https://qiita.com/over_di/items/1270d3737e0a81719e56
1 | .dt.time |
をつければOK
1 2 3 | dfs2[ "発表時間" ] = pd.to_datetime(dfs2[ "発表時間" ], format = "%H:%M" ,errors = 'coerce' ).dt.time dfs2 |
とすることで無事に変換できた
次は時刻に応じてカレンダーの列を取り出すようにする
オブジェクトを調べたら
1 | to_datetime() |
では型変換されていない
元の状態を
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | dfs2.dtypes / で調べたら 発表時間 object 経済指標 object 前回変動幅(USD / JPY) object 前回 object 予想 object 結果 object dtype: object |
となっていた