結論分析するときに使うコードをrxで書く必要ないと思う。
けど勉強のために練習で書いて見た。
ReactiveX、Rx
observableイベントストリームでプログラミングするためのAPI。
"Rx = Observables + LINQ + Schedulers"
3つの組み合わせを使用することでコードを簡潔にかける。
環境
pip install rx
python2. 3.
ただし2.の場合はfrom future import print_functionをはじめに書くこと。
- Getting Started with RxPY
ちょっと動かしてみる場合はこっちへ
普通のコードとの比較
リストをちょっと増やしたいなーってときのコードを比較
リストを増やしてるところまでなので、あとはリストを自由に使ってください。
import cv2
import os, glob
images = glob.glob('./train/*.png')
aug_times = 3
for times in range(aug_times):
for img in images:
img_name = os.path.basename(img)
print(img_name.replace(".png", "_"+str(times)+".png"))
#print(img)
#img = cv2.imread(images)
#print(img)
#cv2.imwrite('copyJohn.jpg', img)
break
from __future__ import print_function
import cv2
import os, glob
import rx
from rx import Observable, Observer
def re_file_name(img, times):
return os.path.basename(img).replace(".png", "_"+str(times)+".png")
def push_five_strings(observer):
aug_times=3
filepath = './train/*.png'
images = glob.glob(filepath)
[observer.on_next(re_file_name(img, times)) for img in images for times in range(aug_times)]
def to_list(r):
return auged_files.append(r)
auged_files = []
source = Observable.create(push_five_strings)
source.subscribe(lambda r : to_list(r))
print(auged_files[0])
途中経過
mvp的な考えでObservableなオブジェクトにリストを渡してsubscribeってするとprint関数に値が渡されて実行されていく。
subscribe前にmapでlenに変換したり、filterで絞ったりlinqの操作ができる。
あとタイミングを操作したりもできる。
from __future__ import print_function
import cv2
import os, glob
import rx
from rx import Observable, Observer
Observable.from_(["a","b","c"]).subscribe(print)
Observable.from_(["aaa","bb","c"]).subscribe(print)
Observable.from_(["aaa","bb","c"]).map(lambda s: len(s)).subscribe(print)
Observable.from_(["aaa","bb","c"]).map(lambda s: len(s)).filter(lambda i: i == 3).subscribe(print)
リスト増幅部分を2重内包表記で書いて見たけども、Observable.from_の中にメソッド2重になってて見た目がダサい感。
def get_files(filepath='./train/*.png'):
return glob.glob(filepath)
def re_file_name(img, times):
return os.path.basename(img).replace(".png", "_"+str(times)+".png")
def aug_files(images, aug_times=3):
return [re_file_name(img, times) for img in images for times in range(aug_times)]
Observable.from_(aug_files(get_files())).subscribe(print)
ということでobserverなオブジェクトにon_nextで内包表記で突っ込んでcreateした。
from __future__ import print_function
import cv2
import os, glob
import rx
from rx import Observable, Observer
def re_file_name(img, times):
return os.path.basename(img).replace(".png", "_"+str(times)+".png")
def push_five_strings(observer):
aug_times=3
filepath = './train/*.png'
images = glob.glob(filepath)
[observer.on_next(re_file_name(img, times)) for img in images for times in range(aug_times)]
def to_list(r):
return auged_files.append(r)
auged_files = []
source = Observable.create(push_five_strings)
source.subscribe(lambda r : to_list(r))
print(auged_files[0])
これで良かったのか不明だけど一応動いた。
参考
Getting Started with RxPY
https://github.com/miyamotok0105/RxPY/blob/a883f423818376674c4906bc9f5754fed969288a/notebooks/Getting%20Started.ipynb