久しぶりにヤバそうなのが来た
どうもこんにちは。現在の会社を休職中で転職活動をしておりpythonを勉強している筆者です。先日、2月の給料が振り込まれましたが普段の8割くらいでした。有給が切れたからかな。こでじゃ3月の給料は入らないのか?まあ働いてないから仕方ないけど。まず傷病手当金の申請しなきゃ。しかし会社の健康保険組合のホームページ見たら、傷病手当金て申請してから支給まで最低でも2ヶ月かかるって。。これのどこが生活保障だよ。終わってるわ。
定期的に来る家庭イヤイヤ期でもあります。こんな時でもまったく自分でお金を稼ごうとしない嫁。。どんだけ人任せなんだよ。。専業主婦って終わってるわ。20代前半で結婚したのはまじで失敗だった。今30代前半の俺らは親がバリバリの専業主婦世代だからしょうがないかもしれないが、これから嫁は稼げるとしてもパートで年100万円。パートって仕事も減っていくだろうから、これからはそれすら厳しかもしれない。そんな女性の生活費を一生負担していくってどんな罰ゲームだよ。。勘弁してくれ。(いまは子どもが小さいから、子育てをあまりやってない俺が稼ぐのは当然だと思ってるが。)
ということで毒を吐きました。久しぶりに悪い感情が襲ってきてます。昨日までは元気だったんだけどな。こんな状態じゃ転職活動うまくいきっこない。はあ、もうやだ。久々にメンヘラって色んなことにすごく苛ついてます。明日になれば元気になるんだろうか。
python pandasの添字「[0:1]」と「iloc[0]」の違いについて
転職活動中ですが、相変わらずpythonのプログラム書いて遊んでます。さて今回は表題のことが気になったので試してみました。両方ともリスト(配列)の1レコード目を持ってくるという意味っぽいですが何が違うのでしょうか。サンプルのテストコードは以下のとおり。ちなみに完全に自分用のメモです。
import pandas.io.sql as psql #データベース「nikkei」の「nk225days」テーブルから日時順に並び替えて、「年月日、時刻、終値」のデータを取り出す。 conn = mysql.connector.connect(user='root', password='yashiro3', host='localhost', database='nikkei') sql = """SELECT date,time,start,end FROM nk225days WHERE end <> 0 AND date > '20120101' order by date asc,time asc ;""" n225fm = psql.read_sql(sql, conn) da0 = n225fm[0:1].date # 1レコード目の日付 da1 = n225fm.iloc[0].date print(n225fm) print("n225fm[0:1] = {0}".format(da0)) print("") print("n225fm.iloc[0] = {0}".format(da1))
出力結果はこのとおり。その値だけを取り出したいときは「iloc」を使って指定するんだね。「[0:1]」って指定をすると確かに1レコード目が取り出されるんだけど、インデックス番号やら型情報も取り出すようです。
date time start end 0 2012-01-04 09:00:00 8535 8540 1 2012-01-04 16:30:00 8525 8505 (省略) n225fm[0:1] = 0 2012-01-04 Name: date, dtype: object n225fm.iloc[0] = 2012-01-04
SQLで時刻を指定して抽出する
結構な時間ハマったのでメモ。
データベースのカラムで時刻の項目を持ってるケースもあると思います。で、ある特定の時刻のデータを抽出したいケースってありますよね。SQLのWHERE句でこう書けばいけました。
WHERE TIME_FORMAT(column_name, '%H:%i:%s') = '09:00:00'
これで時刻を指定して抽出できます。はじめ「convert」使って色々やってたんだけど、中々うまくいかなかったので誰かのお役に立てば。
MySQLに日経先物の5分足データCSVをインポートしたらフリーズした。
相変わらず日経先物の過去データを集めています。過去の日足および最近の日中分足はwebからスクレイピングで取得しました。
ちなみにスクレイピングはこちらのサイト様にお世話になりました。
(サイト運営者様、サーバーに負荷かけてしまったかもしれないです。申し訳ありません。)
ただし、日中分足については最近のデータ(30分足は過去4ヶ月。15分足、5分足は過去4日)しかweb上にありません。そのため過去のデータについては別のところから取得する必要があります。ということで、ここから過去の日中分足をダウンロード。2012年〜のデータがあります。
225labo.com
で、このCSVをMySQLに格納するためのプログラムをrubyで書きました。MySQLのコマンドで単純にインポートしても良かったんですが、取引日を加工してMySQLに格納したかったので、プログラムでやりました。
require 'mechanize' require "active_record" require "date" require "time" ActiveRecord::Base.establish_connection( adapter: "mysql2", host: "localhost", username: "root", password: "xxxxxx", database: "nikkei", ) class Test < ActiveRecord::Base end today = 0 tomorrow = 0 regist = 0 FILE_NAME = 'n225_5.csv' File.open(FILE_NAME) do |file| file.each_line do |line| regist += 1 vals = line.split(',') #------取引日の加工----------# #ナイト・セッション(24時まで)は当日の日付に変更する。 if vals[1].to_i == 9 today = vals[0] end if vals[1].to_i >= 16 vals[0] = today end #ナイト・セッションの24時以降は当日の翌日日付とする。(金曜ナイトの24時以降は土曜の日付となる。) if vals[1].to_i >= 0 && vals[1].to_i <= 5 tomorrow = Date.parse(today) vals[0] = tomorrow + 1 end #30分足の場合、朝のスタート時間をデータ上8時半にする。(ほんとのスタート時間は8時45分) # if vals[1].to_i == 8 # vals[1] = "08:30:00" # end #-----取引日の加工終了----------# attr = {date: vals[0], time: vals[1], start: vals[2], high: vals[3],low: vals[4],end: vals[5],volume: vals[6]} test = Test.new(attr) if test.save puts "data insert done!! #{regist}" else #データの保存でエラーとなったときはABENDさせる。 puts "error" exit(1); end end puts "data insert END!!" end
こんなプログラムで30分足、15分足、5分足のCSVデータをMySQLに格納していきます。5分足については2012年〜のデータで約30万件ありました。。この30万件を処理してたら、MySQLが動かなくなります。。
MySQLがフリーズしたときは以下のようにやれば解決しました。これでようやくデータの準備は完了です。やっと分析フェーズに入れそうです。長かった。1週間くらいかかったぜ!!
mysql> show processlist; +-----+------+-----------+--------+---------+------+----------+------------------+ | Id | User | Host | db | Command | Time | State | Info | +-----+------+-----------+--------+---------+------+----------+------------------+ | 11 | root | localhost | nikkei | Sleep | 58 | | NULL | | 12 | root | localhost | NULL | Sleep | 18 | | NULL | | 116 | root | localhost | NULL | Query | 0 | starting | show processlist | +-----+------+-----------+--------+---------+------+----------+------------------+ mysql> kill 11; mysql> kill 12;
MySQLにタイムスタンプを追加する。
「test」テーブルの最後のカラムの後ろに、レコードの作成時間を格納するカラムを追加します。
カラム名の後ろに「TIMESTAMP DEFAULT CURRENT_TIMESTAMP」と書きます。
ALTER TABLE tests ADD create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP AFTER last_column;
次に「test」テーブルの最後のカラム(先程追加した「create_time」)の後ろに、レコードの更新時間を格納するカラムを追加します。レコードを更新したときに更新時間を格納するにはカラム名の後ろに「TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP」をくっつけます。
ALTER TABLE tests ADD update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP AFTER create_time;
では試してみます。
まず「tests」テーブルにレコードを追加します。
INSERT INTO tests(date,time) values('20170101','090000'); SELECT * FROM tests;
中身はこうなってます。
レコード作成時間が格納されてます。(右にスクロールさせてください)
+----+------------+----------+-------+------+------+------+--------+-------+---------------------+---------------------+ | id | date | time | start | high | low | end | volume | value | create_time | update_time | +----+------------+----------+-------+------+------+------+--------+-------+---------------------+---------------------+ | 2 | 2017-01-01 | 09:00:00 | NULL | NULL | NULL | NULL | NULL | NULL | 2017-02-23 21:35:53 | 2017-02-23 21:35:53 | +----+------------+----------+-------+------+------+------+--------+-------+---------------------+---------------------+
次に先程追加したレコードを変更します。
UPDATE tests set date = '20170401'; SELECT * FROM tests;
中身はこう。update_timeだけ変更されてます。(右にスクロールさせてください。)
+----+------------+----------+-------+------+------+------+--------+-------+---------------------+---------------------+ | id | date | time | start | high | low | end | volume | value | create_time | update_time | +----+------------+----------+-------+------+------+------+--------+-------+---------------------+---------------------+ | 2 | 2017-04-01 | 09:00:00 | NULL | NULL | NULL | NULL | NULL | NULL | 2017-02-23 21:35:53 | 2017-02-23 21:38:35 | +----+------------+----------+-------+------+------+------+--------+-------+---------------------+---------------------+
pythonでNT倍率を表示してみる。
MySQLに保存した日経先物とTOPIX先物の日足データを使ってNT倍率をグラフ化してみました。
出力したグラフはこんな感じ。2008年10月のリーマンショック時に9.5をつけてから右肩上がり。
ソースコードはこれ。グラフの縦横比ってどうやって変更するんだろう。plt.figure(figsize=(x, y)) でも変更されなかったんだよな。。
%matplotlib inline import pandas as pd import numpy as np import mysql.connector import pandas_datareader.data as pdr import matplotlib.pyplot as plt import datetime import seaborn as sns day_array = [] nk_array = [] tp_array = [] nt_array = [] #データベース「nikkei」の「nk225days」テーブルから日時順に並び替えて、「年月日、時刻、終値」のデータを取り出す。 conn = mysql.connector.connect(user='root', password='xxxxxx', host='localhost', database='nikkei') #日経先物、TOPIX先物の日中終値を取得 cur_nk = conn.cursor(buffered=True) cur_nk.execute("SELECT date,time,end FROM nk225days WHERE time='09:00:00' order by date asc,time asc ;") cur_tp = conn.cursor(buffered=True) cur_tp.execute("SELECT date,time,end FROM tpdays WHERE time='09:00:00' order by date asc,time asc;") #終値がゼロ(取引がない)ときを除いて、データを配列に格納する。 for row in cur_nk.fetchall(): if not row[2] == 0: day_array.append(row[0]) nk_array.append(row[2]) #終値がゼロ(取引がない)ときを除いて、データを配列に格納する。(日経先物のデータがある取引日のみ) for row in cur_tp.fetchall(): for day in day_array: if row[0] == day: if not row[2] == 0: tp_array.append(row[2]) #NT倍率を格納 for i in range(len(day_array)): nt_array.append(nk_array[i]/tp_array[i]) # #NT倍率を表示 # for i in range(len(day_array)): # print (day_array[i],nt_array[i]) #NT倍率のグラフを表示 plt.plot(day_array, nt_array,color='red') plt.grid(which='major', color='k',linestyle=':') plt.title("NIKKEI / TOPIX ratio") plt.tick_params(labelsize=12) plt.figure(figsize=(3, 1)) plt.show() cur.close conn.close