夢に向かって、好奇心を持ち、疑問を持ち続ける。それが努力。

趣味でロボット職人を目指す自称AI研究者のメモです。

Pythonの上位モジュールがimportできない!→コマンドをモジュール実行!

皆様お元気でしょうか.
ご無沙汰してしまいましたが,最近コード書いていて詰まった話をメモしておきます.(初歩的なところですがw)

今回は,ずばり”モジュール化”!


pythonでコードを書いていて,

code/moduleA/testA.py
code/moduleB/testB.py

で,testA.pyからtestBのモジュールをImportしたいときありますよね.

特にtestA.pyの単体テストを想定してます.


testA.pyに以下のように書くとします.

from module B import testB

もちろん,moduleB/__init__.pyはありますが,
'no module named moduleB'
でエラーになります..


うーん??相対パスだからこれかなぁ?

from ..module B import testB

と試しても,'ImportError: attempted relative import with no known parent package'というエラーで怒られます..

ちなみに,
testA.pyを code/test.py のようにcode直下に配置すれば,

from module B import testB

で正常に動きます.でも単体テストで移動したら意味ない!


そんなときは!ずばり!モジュール実行!!です!!
pythonコマンドの-mオプション.

python -m moduleA.testA

のようにコマンドラインに書いてtestA.pyを実行(.pyは不要)すると,testA.py内で以下のようなモジュール呼び出しがあっても正常に動きます.

from module B import testB


ぱちぱちぱち!
同じ様に詰まる人がいたら参考になればと思います〜!

ではまた!

Json形式のファイルを標準出力で見やすく表示する(Linux)

json形式のファイルをvim等で開くと...

うーん.. 見にくい...

ってことありますよね.

そんな時は,jqコマンドが便利です.

まずはインストール.
・sudo権限ありディレクトリへインストールの場合

sudo curl -o /usr/local/bin/jq -L https://github.com/stedolan/jq/releases/download/jq-1.5/jq-linux64 && sudo chmod +x /usr/local/bin/jq

・sudo権限ありディレクトリへインストールの場合

curl -o /home/local/bin/jq -L https://github.com/stedolan/jq/releases/download/jq-1.5/jq-linux64 && chmod +x /home/local/bin/jq

上記のように,/usr/local/bin/jq をsudo権限の不要なお好きなディレクトリに変更すれば,共有サーバ等に個人用にインストールするのも可能です.

コマンドラインで,jq と打って,使えることを確認.(使えなかったらおそらくインストール先にpathが通ってないので,pathを通す.)

使えたら,実際に表示してみよう.
test.jsonを表示したいファイルだとすると,以下を実行.

cat test.json | jq .


おぉ!!!見やすい!!!


ちなみに,dumpするときにちゃんとindentありで出力してれば綺麗に見れるので,そちらのやり方も載せておきますね.

__dict = {'top': {'a': 1, 'b': 2}}
f = open("output.json", "w")
json.dump(__dict, f, ensure_ascii=False, indent=4, sort_keys=True, separators=(',', ': '))

そのまま開いても.

vi output.json

うん,きれい!!!


参考にさせていただいたサイトさん:
 https://qiita.com/wnoguchi/items/70a808a68e60651224a4
 上記サイトでは,sudoつけてますが,例のように/usr/local/bin/jq をsudo権限の不要なお好きなディレクトリに変更すれば,
 sudo権限のない場合でもインストール可能なので,もしそこで詰まった方がいればご参考まで.


以上,json形式のファイルを表示する方法でした〜.
久しぶりの更新でしたね.閲覧,ありがとうございました.

pythonのpandasライブラリの紹介

今日は、pythonライブラリのpandasの紹介です,

pandasを使ったpythonのファイル読み込み・書き込み(特にcsv等)は,とっても簡単.

以下にサンプルを使って紹介します.

import pandas as pd
# 単純にcsvファイルを読み込む時(headerなくデータだけ並んでる時)
df = pd.read_csv("data.csv",header=None)

# headerに名前をつける時
df = pd.read_csv("data.csv",header=None, names=('a','b','c'))

# tsvデータを開く時はdelimiterを指定
df = pd.read_csv('data.tsv', delimiter='\t')

# pandasで書き出す時
df.to_csv('out.csv')

簡単ですね.
ちなみに,読み込んだデータはDataFrameという形式になっています.

ので,検索や列の取得などいろいろ楽にできます.

データから条件を指定して値を抽出したい時

# 0と一致しているものを抽出
data = df[df['a'] == '0']

# 正規表現で数字のものを抽出
data = df[df['a'].str.contains('\d')]

# NaNを除去したい時
data = df.fropna()

# 列を指定して除去することも可能
data = df.dropna(subset=['a', 'b'])

# 列の結合(df2というコピーを作って統合する場合)
df2 = df.copy(deep==True)
data = pd.concat([df1,df2])

# 行列の転置もできます
data = df.T


なお,読み込んだデータの各列の型が知りたい時には,headerの情報を取得して,以下のように記載すると取得できます.

# データの型(数字か文字列かなど)が知りたい時
df['a'].dtype


以上.

続きはまた紹介します.

Jupyter Notebookの使い方

Jupyter Notebookとはpythonの快適な開発環境です.

セル単位ごとに実行して結果を確認できるので,デバッグに便利.

Jupyter Notebookのインストールはこちらから.
http://jupyter.org/install.html

ターミナルで使いたいディレクトリに移動し,

cd ...
jupyter notebook

で起動できます.

サーバで起動する場合には,

jupyter notebook --generate-config

で,ホームに出来上がったjupyter_notebook_config.pyに,

c.NotebookApp.ip = '*' # localhost以外からもアクセス可能にするおまじない.じゃないか(笑)
c.NotebookApp.port = 8888 # サーバのポート.デフォルト8888.
c.NotebookApp.open_browser = False # ブラウザを自動で開くようにしたいときはFalse
c.NotebookApp.notebook_dir = '/home/user/jupyter' # 作業ディレクトリ.

上記を記述して,jupyter notebookコマンドで起動.


プラウザで http://[server ip adress]:8888/ にアクセスしたらOK.

ノードブックの作成は,右上の"New"ボタンから.

実行には,ctrl+Enter,
セルを作成する場合には, Shift+Enter.

Anacondaも自動でインストールできるので,numpyやpandasなどいろいろ支えて便利.


簡単ですが,メモでしたー.以上です.

知らなかったpythonのrandint

pythonで,ある値の範囲からランダムに数字(ここではint型の数字)を選択するときrandint関数を使うが,どうやら値の範囲がnumpyを使う場合とpython標準のrandom関数を使う場合とで違うらしい.

aからbまでを範囲とするとき.

random.randintの場合は,[a,b]のようにbが含まれるが,
numpy.random.randintの場合は,[a,b)のように,bは含まれない.

違いはこの通り.

>>> import numpy as np
>>> import random
>>> a=0
>>> b=3
>>> i=10

>>> # random関数を使ったとき
>>> while i > 0:
...     print random.randint(a,b)
...     i = i -1
... 
3
2
3
0
3
2
0
0
2
2
>>> # numpyのrandom関数を使ったとき
>>> i=10
>>> while i > 0:
...     print np.random.randint(a,b)
...     i = i -1
... 
0
0
0
2
2
1
1
2
2
2
>>> 

複数の言語を使う場合には,同じ名前でも同様のことができる関数と思わないようにとは思っていたけど,
同一言語でも,まさか異なるポリシーの関数があったとは!

やっぱりライブラリの関数を使う場合には,確認が必要ですね:)

googleのword2vecを使ってみる(on Mac)

word2vecって良くきくので,昨年googleが公開したword2vecを使ってみたいと思います.

インストールは簡単

git clone https://github.com/svn2github/word2vec.git

でgitから取ってくるだけ.

cd word2vec でディレクトリに入り,
make が通れば完了.

私の環境では(特にmacでは)
malloc.hがないと怒られたので.

#include <malloc.h>

を全て

#include <stdlib.h>

に変更.

無事にコンパイルが通りました.

あとは,

./demo-word.sh

を実行して,単語を入力すればデモの試し成功!

と思ったら,
wgetコマンドがなくてtrain用データのインストールが失敗していた.

gzip: can't stat: text8.gz (text8.gz.gz): No such file or directory

ので,demo-word.shの中でwgetコマンドを curl -o に変更.

curl http://mattmahoney.net/dc/text8.zip -o text8.gz

さらに,
ERROR: training data file not found!

と怒られたが,
http://mattmahoney.net/dc/text8.zipがうまく保存できていなかったり
パスの指定が誤ってたりすると,解凍に失敗するので,
上記エラーがでたときは,保存データの容量等でうまく保存できているか確認すると良さそうです.


ロードと学習が成功すれば,次回以降は,毎回学習する必要はないので,

./distance vectors.bin

だけで使えます.

以上!


<参考>
malloc.hについては以下のページにお世話になりました.感謝!
http://blog.tottokug.com/entry/2014/04/17/160603

pythonの文字コードについて

pythonは文字列処理が得意だけど日本語を扱うときは文字コードがちょっと厄介だったりする.

特に注意が必要なunicode型とstr型について私がはまったところをメモ.

やりたかったことは,キーに日本語文字列を持つ辞書に対して,標準入力で取得した日本語文字列との比較を行いマッチしたら”OK”を返すというもの.

これに対して,同じ日本語であるはずなのに,比較で失敗する事象が発生した.
最初から文字コードを疑っていたので.全てのファイルに
# coding: utf-8
を記載.ファイル読み込みなどの箇所は,全て,’utf-8’にした.

しかし,まだ一致しない..

疑ったのは,unicode, stringの型の違い.

やっぱりそうだった.


 pythonから標準入力をするとき,入力はstring形式である.

 しかし,辞書のキーに日本語文字列を用いるとき,unicode型で保存される.

従って,辞書の中に標準入力から取得した文字列そのままを当てはめようとすると,失敗する.

以下に成功する例と失敗する例を記載する.

def proc(instr):
    // 失敗する例
    if instr in dic.keys():
        print “this cannot match”

    // 成功する例
    units = unicode(instr, ‘utf-8’)
    if units in dic.keys():
        print “this can succeed to match”

while(True):
    line = raw_input('input : ')  
    ## for stdin
    insert = proc(line) 
    print instr

ちなみにdicは,
dic={u'あ':aaa, u'い':iii}
のような形式を想定.

以上.

ご参考まで:)