mysqlでのテーブルの1対多のjoin。
mysqlでのテーブルの1対多のjoin。
TABLE_SECには、5秒ごとのデータが入っている。
TABLE_HOURには、1時間ごとのデータが入っている。
10:00:06の時点では、10:00:00からの5秒間のデータは確定しているが、
10:00:00から1時間のデータは確定していない。
そのため、9:00:00から1時間のデータを参考の資料として対応づける。
TABLE_SECでは、timeShift1、timeShift2は使用していないが、同じテーブル構成になるように定義を残している。
TABLE_HOURでは、timeShift1は1時間先、timeShift2は2時間先の時刻を指している。
INNER JOINで2つの条件で1件に絞ってJOINしている。
# -*- coding: utf-8 import mysql.connector import datetime config = { 'user': 'root', 'password': 'Password', 'host': 'localhost', 'database':'testdb', 'charset':'utf8' } cnx = mysql.connector.connect(**config) cur = cnx.cursor(buffered=True) sql = 'DROP TABLE IF EXISTS TABLE_SEC;' cur.execute(sql) cnx.commit() sql = 'DROP TABLE IF EXISTS TABLE_HOUR;' cur.execute(sql) cnx.commit() sql = 'CREATE TABLE IF NOT EXISTS TABLE_SEC (id INT UNSIGNED NOT NULL AUTO_INCREMENT,\ time DATETIME DEFAULT NULL, \ timeShift1 DATETIME DEFAULT NULL, \ timeShift2 DATETIME DEFAULT NULL, \ volume INT UNSIGNED DEFAULT NULL,\ valid INT UNSIGNED DEFAULT NULL ,\ primary key(id),\ unique (time));' cur.execute(sql) cnx.commit() sql = 'CREATE TABLE IF NOT EXISTS TABLE_HOUR (id INT UNSIGNED NOT NULL AUTO_INCREMENT,\ time DATETIME DEFAULT NULL, \ timeShift1 DATETIME DEFAULT NULL, \ timeShift2 DATETIME DEFAULT NULL, \ volume INT UNSIGNED DEFAULT NULL,\ valid INT UNSIGNED DEFAULT NULL ,\ primary key(id),\ unique (time));' cur.execute(sql) cnx.commit() sql='INSERT INTO TABLE_SEC (time,timeShift1,timeShift2,volume,valid) VALUES("2016-12-12T9:59:55","2016-12-12T10:00:00","2016-12-12T10:00:5",1,0);' cur.execute(sql) cnx.commit() sql='INSERT INTO TABLE_SEC (time,timeShift1,timeShift2,volume,valid) VALUES("2016-12-12T10:00:00","2016-12-12T10:00:05","2016-12-12T10:00:10",1,1);' cur.execute(sql) cnx.commit() sql='INSERT INTO TABLE_SEC (time,timeShift1,timeShift2,volume,valid) VALUES("2016-12-12T10:00:05","2016-12-12T10:00:10","2016-12-12T10:00:15",1,2);' cur.execute(sql) cnx.commit() sql='INSERT INTO TABLE_SEC (time,timeShift1,timeShift2,volume,valid) VALUES("2016-12-12T11:00:10","2016-12-12T11:00:15","2016-12-12T11:00:20",1,3);' cur.execute(sql) cnx.commit() sql='INSERT INTO TABLE_SEC (time,timeShift1,timeShift2,volume,valid) VALUES("2016-12-12T11:00:15","2016-12-12T11:00:20","2016-12-12T11:00:25",1,4);' cur.execute(sql) cnx.commit() sql='INSERT INTO TABLE_SEC (time,timeShift1,timeShift2,volume,valid) VALUES("2016-12-12T10:00:20","2016-12-12T10:00:25","2016-12-12T10:00:30",1,5);' cur.execute(sql) cnx.commit() sql='INSERT INTO TABLE_HOUR (time,timeShift1,timeShift2,volume,valid) VALUES("2016-12-12T8:00:00","2016-12-12T9:00:00","2016-12-12T10:00:00",2,8);' cur.execute(sql) cnx.commit() sql='INSERT INTO TABLE_HOUR (time,timeShift1,timeShift2,volume,valid) VALUES("2016-12-12T9:00:00","2016-12-12T10:00:00","2016-12-12T11:00:00",2,9);' cur.execute(sql) cnx.commit() sql='INSERT INTO TABLE_HOUR (time,timeShift1,timeShift2,volume,valid) VALUES("2016-12-12T10:00:00","2016-12-12T11:00:00","2016-12-12T12:00:00",2,10);' cur.execute(sql) cnx.commit() sql='INSERT INTO TABLE_HOUR (time,timeShift1,timeShift2,volume,valid) VALUES("2016-12-12T11:00:00","2016-12-12T12:00:00","2016-12-12T13:00:00",2,11);' cur.execute(sql) cnx.commit() sql='INSERT INTO TABLE_HOUR (time,timeShift1,timeShift2,volume,valid) VALUES("2016-12-12T12:00:00","2016-12-12T13:00:00","2016-12-12T14:00:00",2,12);' cur.execute(sql) cnx.commit() #ここからが本題。 #SELECT * FROM TABLE_HOUR INNER JOIN TABLE_SEC ON TABLE_SEC.time >=TABLE_HOUR.timeShift1 AND TABLE_SEC.time < TABLE_HOUR.timeShift2; sql='SELECT TABLE_SEC.id,TABLE_SEC.time,TABLE_HOUR.time FROM TABLE_HOUR INNER JOIN TABLE_SEC ON TABLE_SEC.time >=TABLE_HOUR.timeShift1 AND TABLE_SEC.time < TABLE_HOUR.timeShift2;' cur.execute(sql) record = cur.fetchone() while record!=None: print(record) record = cur.fetchone() cur.close() cnx.close()
結果
(1, datetime.datetime(2016, 12, 12, 9, 59, 55), datetime.datetime(2016, 12, 12, 8, 0)) (2, datetime.datetime(2016, 12, 12, 10, 0), datetime.datetime(2016, 12, 12, 9, 0)) (3, datetime.datetime(2016, 12, 12, 10, 0, 5), datetime.datetime(2016, 12, 12, 9, 0)) (6, datetime.datetime(2016, 12, 12, 10, 0, 20), datetime.datetime(2016, 12, 12, 9, 0)) (4, datetime.datetime(2016, 12, 12, 11, 0, 10), datetime.datetime(2016, 12, 12, 10, 0)) (5, datetime.datetime(2016, 12, 12, 11, 0, 15), datetime.datetime(2016, 12, 12, 10, 0))
pythonで逐次入力に対して移動平均を計算するためのクラス
pythonで、逐次入力に対して移動平均を計算する。
移動平均幅は、コンストラクタの引数に与えておく。
以下、ソース。
# -*- coding: utf-8 -*- class MovingAverage: """逐次入力に対して移動平均を計算するためのクラス""" def __init__(self,size): # コンストラクタ self.pc = 0 self.data=[0]*size #リングバッファとして使う self.size=size self.full=False def put(self,value): self.data[self.pc]=value self.pc=self.pc+1 if self.pc==self.size: self.pc = 0 self.full=True return self.full def print(self): #デバッグ向けリングバッファの中身確認用 print(self.data) def average(self): if self.full: return sum(self.data)/self.size else: #入力が足りないときにも一応値を返してみる。 return sum(self.data)/self.pc def main(): mv2=MovingAverage(3) mv2.put(4) mv2.print() print(mv2.average()) mv2.put(5) mv2.print() print(mv2.average()) mv2.put(6) mv2.print() print(mv2.average()) mv2.put(7) mv2.print() print(mv2.average()) if __name__== '__main__': main()
実行結果
C:\Python34>C:\Python34\python.exe C:\Python34\movingaverageclass.py [4, 0, 0] 4.0 [4, 5, 0] 4.5 [4, 5, 6] 5.0 [7, 5, 6] 6.0
Matlab 2016bのwebreadがおかしい
Matlab 2016bのwebreadの動きがおかしかったのでメモ。
原因?
URLの中にある時刻の表現の中で%3Aのエンコードがおかしなことになってることが判明。
URLの中に%3Aを含めると%253Aになったり、:(コロン)で表現するとコロンのままで、%3Aにならなかったり。
暫定対策
C:\Program Files\MATLAB\R2016b\toolbox\matlab\external\interfaces\...
webservices\http\+matlab\+net\QueryParameter.m(429,9)
noEncodeCharsの'/?'を'/?%'に変更して、%を%のままエンコードしないように指定すると、とりあえず動いた。
メモ
アクセス権がないので、Administrator権限で、編集権限を与えてから編集しましょう。
PythonからMatlabの関数を呼び出す
matlab.engineのインストール
管理者権限で起動したコマンドプロンプトで以下を実行
cd "C:\Program Files\MATLAB\R2016a\extern\engines\python\" C:\Python34\python.exe "C:\Program Files\MATLAB\R2016a\extern\engines\python\setup.py" install
なぜか「ImportError: No module named 'matlab'」
実行するとこんなエラーに。
ImportError: No module named 'matlab'
matlab.engineは以下にあります。
C:\Python34\Lib\site-packages\matlab\engine
解決策1 環境変数でPYTHONPATHを指定して実行する
C:\Program Files\MATLAB\R2016a\extern\engines\python>SET PYTHONPATH="C:\Python34\Lib\site-packages" C:\Program Files\MATLAB\R2016a\extern\engines\python>"C:\Python34\python.exe" "C:\Users\Cucco\Documents\MATLAB\matengen.py" [[1.0,2.0,3.0,4.0,5.0]]
解決策2 実行する.pyファイルの中でパスを記載する
# -*- coding: utf-8 import sys sys.path.append('C:\Python34\Lib\site-packages') import matlab.engine eng = matlab.engine.start_matlab() a = matlab.double([1,4,9,16,25]) b = eng.sqrt(a) print(b)
実行結果
C:\Python34>C:\Users\Cucco\Documents\MATLAB\matengen.py [[1.0,2.0,3.0,4.0,5.0]]
Matlabで1×Nのサイズのベクトルを2次元配列に変換
まずは変換のルールを確認
3×4の2次元配列を用意。
>> a=[[1 2 3 4]; [5 6 7 8]; [9 10 11 12]] a = 1 2 3 4 5 6 7 8 9 10 11 12
reshape()で1×Nに変換。列方向に拾って1×Nを作る様子。
>> b=reshape(a,1,[]) b = 1 5 9 2 6 10 3 7 11 4 8 12
4列の形にしてほしいので、reshape()でn×4に変換。元に戻りました。
>> c=reshape(b,[],4) c = 1 2 3 4 5 6 7 8 9 10 11 12
元に戻りました。
行方向で2次元配列を拾って行ってほしい
手元にあるデータの並びは行方向に拾った感じのデータなので、それを2次元配列にしたい。
1×nのベクトルを用意。
>> d=[1 2 3 4 5 6 7 8 9 10 11 12] d = 1 2 3 4 5 6 7 8 9 10 11 12
あとで転置するので、行を4行になるようにreshape()
>> e=reshape(d,4,[]) e = 1 5 9 2 6 10 3 7 11 4 8 12
転置すると期待通りに。
>> f=transpose(e) f = 1 2 3 4 5 6 7 8 9 10 11 12
PythonからMySQLを操作する
構築
Python3.4とMySQL5.7を利用。
Pythonを先に入れておく。Python のバージョンは、Connectorの対応バージョンと合わせておく。
MySQLのインストール時には、rootユーザのパスワードの設定が必要。ここでは、passwordとします。
Connector
http://dev.mysql.com/downloads/connector/python/
Connector自体は、MySQLのインストーラに含まれている様子。
準備
データベースを作ります。
スタートメニューにいる”MySQL 5.7 Command Line Client - Unicode”を開いて、ログイン。
最初はこんな感じのデータベースがある。show databases;がコマンド。
mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sakila | | sys | | world | +--------------------+ 6 rows in set (0.00 sec)
データベースを作ります。create database testdb;がコマンド。testdbがデータベース名。
mysql> create database testdb; Query OK, 1 row affected (0.01 sec) mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sakila | | sys | | testdb | | world | +--------------------+ 7 rows in set (0.00 sec)
テストコード
pythonで以下を実行
# -*- coding: utf-8 import mysql.connector config = { 'user': 'root', 'password': 'password', 'host': 'localhost', 'database':'testdb', 'charset':'utf8' } cnx = mysql.connector.connect(**config) cur = cnx.cursor(buffered=True) sql = 'DROP TABLE IF EXISTS pet;' cur.execute(sql) cnx.commit() sql = 'CREATE TABLE pet (name VARCHAR(20), owner VARCHAR(20),species VARCHAR(20), sex CHAR(1), birth DATE, death DATE);' cur.execute(sql) cnx.commit() # select cur.execute('SELECT * FROM pet;') row = cur.fetchone() sql = 'INSERT INTO pet VALUES (%s, %s, %s, %s, %s, %s);' data= ('Puffball','Diane','hamster','f','1999-03-30',None) cur.execute(sql, data) sql = 'INSERT INTO pet VALUES (%s, %s, %s, %s, %s, %s);' data= ('Puffball','Diane','hamster','m','1999-03-30',None) cur.execute(sql, data) cnx.commit() # select cur.execute('SELECT * FROM pet;') row = cur.fetchall() # 出力 for i in row: print(i) cur.close() cnx.close()
実行結果
C:\Python34>python C:\Python34\msql_test.py ('Puffball', 'Diane', 'hamster', 'f', datetime.date(1999, 3, 30), None) ('Puffball', 'Diane', 'hamster', 'm', datetime.date(1999, 3, 30), None)
MySQL 5.7 Command Line Clientでテーブル定義の情報を見てみると
mysql> describe pet; +---------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------+-------------+------+-----+---------+-------+ | name | varchar(20) | YES | | NULL | | | owner | varchar(20) | YES | | NULL | | | species | varchar(20) | YES | | NULL | | | sex | char(1) | YES | | NULL | | | birth | date | YES | | NULL | | | death | date | YES | | NULL | | +---------+-------------+------+-----+---------+-------+ 6 rows in set (0.00 sec)
mysql> select * from pet; +----------+-------+---------+------+------------+-------+ | name | owner | species | sex | birth | death | +----------+-------+---------+------+------------+-------+ | Puffball | Diane | hamster | f | 1999-03-30 | NULL | | Puffball | Diane | hamster | m | 1999-03-30 | NULL | +----------+-------+---------+------+------------+-------+ 2 rows in set (0.00 sec)
移動平均
移動平均を返す関数movingAverage。
function [ output_args ] = movingAverage(dataNx1,AverageWindowSize )
filterfunc=ones(1,AverageWindowSize);
output_args = filter(filterfunc,AverageWindowSize,dataNx1);
end
テストコード。yとして、sin関数の値にランダムノイズを加えておく。
x=0:0.05:2*pi;
y=sin(x)+rand(size(x))*0.1;
plot(x,y)
hold on
plot(x,movingAverage(y,5))
結果。青がy。赤が移動平均。