markdown形式にDataframeを変換できるpytablewriterが便利

Dataframe型のテーブルをmarkdown形式の表にするのにいいライブラリを見つけた.これは便利...

使い方を記事から引用します

import pytablewriter

writer = pytablewriter.MarkdownTableWriter()
writer.from_dataframe(df)
writer.write_table()

参考

qiita.com

github.com

pandas の apply で使えるプログレスバーに感動した

tqdm というライブラリでfor文でプログレスバーを表示する方法はよく見ますが, pandasでapplyする時にも対応していて感動しました.

一行足すだけで簡単に使えました.

from tqdm import tqdm
tqdm.pandas()
df.hoge.progress_apply(myfunc)

f:id:akari000:20200108134653p:plain


参考

stackoverflow.com

pandas-operationspypi.org

TAAI2019で発表してきた

初めての学会発表に行ってきました. 忘れないうちに色々書いておこうと思います. f:id:akari000:20191129132926p:plain

目次

自分がやっていたこと,思ったことなどをばーっと書いていきます.
- 研究の進め方
- 論文
- 発表

研究の進め方

やったことは全て書くようにしていました.
というよりも,やることを先に決めてタスクに切り分けてgithubのissueにするようにしていました.こうすることで,記録漏れや無駄な作業はかなり少なくなりました.ミーティングで先生や企業の方に進捗を共有するのもissueを見せればいいだけなので楽でした.企業の方や先生からのフィードバックはコメントとして残すようにしていました.

私は手が先に動いてしまうタイプで,「一旦立ち止まって考えてから手を動かすといいよ」と前バイト先の社長にアドバイスしていただいてからこういうやり方をするようになりました.まだ欠陥はあるので今も試行錯誤してます.

グラフや結果はできるだけ綺麗な状態で保存しておくようにしました. その時の環境,データ数,データ,コードの変更(issueと紐づけてbranchを切るか,commitのURLを載せるかしています)も全て書くようにしました.あとあと見返したときにどんな実験の結果か正確でないと実験し直しになるので...

論文

ページ数の制限があり,4ページから6ページでした. 日本語でしっかり書いても,そのまま英語にできないことがあるので,
日本語では箇条書きでポイントだけを書きました.
この時に全体の流れを決めました.有名な学会に出している他の人の論文を見てみて,どんな書き方があるのかなと調べました.
私の場合は,abstract, introduction, datasets, experiments and results, conclusionsという流れにしました.

論文の英語は校正に出しました. 何日で見て欲しいかも選べるようになっていて,2日とかだとかなり高くつくので早めに出しておく方がいいなと思います. 私が出したところは1単語何円と決まっていて,3日くらいで帰ってきました.噂には聞いていましたが,赤字でびっしりでした.

こちらの意図を読み取ってくれないところもあるので 日本語訳と一緒に出すようにすると良いです.

発表

日本語の場合,発表資料は出来るだけ文字が少ない方が見やすいですが,英語での発表だったので,大事なことは全部発表資料に書きました.理由は大きく二つあって,発音の問題で伝わらないことを避けるためと,パワポのノートをがっつり読まないようにするためです.

発表は研究室の先生や留学経験のある友達に何度も見てもらいました.英語での質問もしてもらいました. 質疑応答対策ですが,発表直前に考えられる質問事項をできるだけ書き出しました.質問リストを研究室の先生にみてもらいアドバイスをもらいました.

f:id:akari000:20191129132749p:plain

今回,嬉しいことに踏み込んだ質問をもらえたのですが日本語でも答えるのが難しいような質問でうまく答えられず... 発表後に質問してくれた方と質問内容についてディスカッションしました.質問事項だけでなく,答えられない問題や,回答が長くなる場合にどうするか考えておくと良いなと思いました.
自分の発表以外にも,同じ分野の発表を聞けるのもとても勉強になりましたし,英語でこう表現するんだな,など発見がありました.またたくさんの人と繋がりができたのが大きかったです.次は三月に国内で学会発表があるのでそれに向けて研究です.

HerokuのpostgreSQLをHobby-devからHobby-basicに移行した時のメモ

データベースのinsertが制限を超えてあと7日で使えなくするよというメールが来てしまいました.

The database DATABASE_URL on Heroku app <app-name> has exceeded its allocated storage capacity. Immediate action is required. The database contains 10,099 rows, exceeding the Hobby-dev plan limit of 10,000. INSERT privileges to the database will be automatically revoked in 7 days. This will cause service failures in most applications dependent on this database. To avoid a disruption to your service, migrate the database to a Hobby Basic ($9/month) or higher database plan:

Hobby-devからHobby-basicに移行してといわれましたが 調べてみるとDBを直接アップグレードするわけではなく,一度有料のAdd-onを追加して,データをコピーする方法を取らないといけないようです. その時のメモです.

手順としては,

  1. Add-onsの追加
  2. DBのURLを取得
  3. 旧DBのバックアップ
  4. アプリをメンテナンスモードにする
  5. 新DBに旧DBのデータをコピー
  6. アプリの参照先を旧DBから新DBに変更
  7. メンテナンスモード解除

という流れです. 以下手順の説明です. <app-name> にはアプリケーションの名前を代入してください.


Add-onの追加

https://dashboard.heroku.com/apps/<app-name>/resources のページのFind more add-onsをクリック f:id:akari000:20191126005058p:plain

Heroku Postgres を選択 f:id:akari000:20191126005102p:plain

Hobby Basicinstall Heroku Postgres を選択 f:id:akari000:20191126005106p:plain

ログイン

heroku login

BDのURLを取得

heroku pg:info --app <app-name>

このような情報が表示されます.
ここで得られる 'DATABASE_URL' と 'HEROKU_POSTGRESQL_BLACK_URL' を後で使います. f:id:akari000:20191126002845p:plain

念のためバックアップを取っておく

heroku pg:backups capture --app <app-name>

新DBに旧DBのデータをコピー DATABASE_URLHEROKU_POSTGRESQL_BLACK_URLは先ほど取得したものを使ってください.

heroku pg:copy DATABASE_URL HEROKU_POSTGRESQL_BLACK_URL --app <app-name>

メンテナンスモードにする

heroku maintenance:on --app <app-name>

アプリが参照するDBの切り替え HEROKU_POSTGRESQL_BLACK_URLは先ほど取得したものを使ってください.

heroku pg:promote HEROKU_POSTGRESQL_BLACK_URL --app <app-name>

DB情報確認

heroku pg:info --app <app-name>

メンテナンスモード解除

heroku maintenance:off --app <app-name>

これで完了です.

Dockerfileとdocekr-compose.ymlの書き方

Dockerfileとdocekr-compose.yml,どっちが先に読まれるのか,どっちもコマンドを使えるがどこまでをどっちのファイルに書くのか,調べてみても様々な書き方が出てきて迷いました...
正解かわかりませんが現時点での自分の理解を載せておきます.



Dockerfileには一つのコンテナを立ち上げるプロセスを書きます.
例としてpython3を使う場合の公式のコードをあげます.

Dockerfile

1   FROM python:3  
2
3   WORKDIR /usr/src/app
4
5   COPY requirements.txt  ./         
6
7   RUN pip install --no-cache-dir -r requirements.txt 
8
9
10  COPY . .                         
11
12  CMD [ "python", "./main.py" ]    

やってること
5行目  ./ 配下 にある requirements.txtをdockerコンテナの中にコピー
7行目  requirements.txtに書かれたライブラリをインストール.
10行目  ./ 配下 にあるディレクトリとファイル全てをdockerコンテナの中にコピー.
12行目 $ python main.pyを実行.このとき$ python3 main.pyとしなくていいのは,python3のイメージのみを使っているため.


docker-compose.ymlにはどのDockerfileを読んで使うかを書きます. このファイルでは複数のコンテナを同時に立てることができます. Dockerfileを選んでイメージを作る仕事だけをさせるのでここにはcommand:はあまり書かない,はずです...
command:を使う場合は,あとで説明する,Dockerfileを自分で書かない場合です. 上のDockerfileを使う場合,最低限のコードを書くとこうなりました.

docker-compose.yml

1  version: '3'   
2  services:  
3    webapp:     
4      build: . 

やってること
1行目  docker-composeのバージョンを指定.
2行目  コンテナの集まりの名前を定義.この名前はよく使われています.
3行目  一つのコンテナの名前を定義.
4行目  ./ にあるDockerfileを使う.という意味



二つのファイルを保存したら,

$ docker-compose build
$ docker-compose up

と叩くと,以下2つのコマンドを叩いたことと同じになります.

$ pip3 -install -no-cache-dir -r requirements.txt
$ python3 main.py

なんだこれだけかという感じですね.これだったらpip3 ooo くらいなら叩くけどなあと思ってしまいますが,コンテナをいくつも建てるとなるとありがたさがわかってきます.

複数のコンテナを建てる場合はこうなります.

1  version: '3'   
2  services:  
3    webapp:     
4      build: . 
5    server:
6      image: redis
7      command: redis-server
8    test:
9      image: minio/minio

webapp, server, test の3つのコンテナを建てました. image : redisでは,Docker Hub に上がっているDockerfileを読み込んで使えます.

https://hub.docker.com/r/minio/minio
https://hub.docker.com/_/redis

これが先ほど言った「自分で書かないDockerfile」です.この場合,打ちたいコマンドをDockerfile内で指定できないのでcommand:を使うことになります.
ここでは「イメージを決める」,「コマンドを叩く」の二種類しかやらせていませんが,ポートの指定や,データ,環境変数の指定もできます.

参考
* Dockerfile Docker Hub
* docekr-compose.yml Compose file version 3 reference | Docker Documentation

Flaskのrequestの仕様でわかったこと

flaskのrequestの仕様ではリクエストのcontent typejson型を設定してpostするとrequest.jsonjsonデータがそのまま入るようです.request.dataにはバイナリで保存されました.

from flask import Flask,request
import json

app=Flask(__name__)

@app.route('/',methods=['POST'])
def index():
    if request.method == 'POST':
        jsondata=request.json
        binary=request.data
        print("request :",request)
        print("request.json :",jsondata)
        print("request.data :",binary)
        return json.dumps(jsondata)
 
def main():
    print('')

if __name__ == '__main__':
    app.run(port=8000)

{'name': 'hanako'} をpost リクエストで送るとこんな感じになります.

request : <Request 'http://localhost:8000/' [POST]>
request.json : {'name': 'hanako'}
request.data : '{\n\t"name" : "hanako"\n}'



リクエストの送信にはコマンドで
$ curl -X POST -H "Content-Type: application/json" -d '{"name":"hanako"}' localhost:8000

のように叩いてもできますが, postman( https://www.getpostman.com/apps )を使いました.UIはこんな感じです.使い方としてはまずrequestのbodyに送るデータを書き,

f:id:akari000:20181223095122p:plain

ヘッダーにデータの種類 Content type : application/json を書きます. f:id:akari000:20181223095222p:plain

return json.dumps(jsondata) としているのでresのbodyにはjsonデータが帰ってきます.
f:id:akari000:20181223095236p:plain

わかったことや詰まったことなどgoogle keepに保存していますがkeepの拡張機能をchromに入れたら気になったことは全部keepに投げてしまってそろそろ整理が必要になってきました...
とりあえず埋もれてしまわないように空いてる時間にここにあげようと思ってるのですがかなり爆速であげていかないと追いつかなそうです笑

並列処理,並行処理

よくどっちがどっちかわからなくなるのでまとめました.

非同期処理 並行処理 いくつかのCPUで処理する
本当に同時に処理をしている
pythonのmultiprocessing
並列処理 待ち時間に他の処理をする
CPUは一つのみ
javascript
pythonのthreading
同期処理 上から一つづつ処理する C, Python, Ruby..(javasqript以外ほぼ全部)

並列処理と並行処理,どちらもいくつかの処理を同時に行うものです.
この二つの違いは簡単にいうと本当に同時に処理しているか.

「並行処理」は実際に複数のCPUを使って同時にプログラムを処理します.一方で「並列処理」は,処理が順不同になるだけで,実際には同時に処理を行なっていません. この場合同期処理でいい気がしてしまいますが一つのプログラムが待ち状態の時に他の処理を行なっているので, 無駄な時間を減らせるメリットがあります.
例としてよくあげられるのは,のライブラリにあるthreadingmultiprocessingですね.
doc↓
threading https://docs.python.org/3/library/threading.html#module-threading
multiprocessing https://docs.python.org/3/library/multiprocessing.html


javascriptは非同期処理と言われますが,実際に同時に処理をしているわけではなく並列処理です.front側の言語では,全て読み込みが終わるまで画面に何も表示されなかったりするのは見る側からするとストレスになるので同期処理ではなく非同期処理が使えるという理解です...
他にも一部だけ見た目を変えたりアニメーションをつけたりするときに毎回処理をしなおさなくてもいいようなプログラムがかけます.