Python

とりあえずrxで書いてみたサンプルコード

結論分析するときに使うコードを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
    ちょっと動かしてみる場合はこっちへ

https://github.com/miyamotok0105/RxPY/blob/a883f423818376674c4906bc9f5754fed969288a/notebooks/Getting%20Started.ipynb

普通のコードとの比較

リストをちょっと増やしたいなーってときのコードを比較
リストを増やしてるところまでなので、あとはリストを自由に使ってください。

aug.py
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  
rx_aug.py
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