Python+R PypeRの使い方
PythonとRを同時に使うことが多いため、PypeRなるライブラリを使ってみます。
ファイル操作はPython、ネットワーク分析はRに軍配が上がると思いますが、往復するのが面倒臭いと思って導入してみました。
sudo pip install pyper
でインストール
import pyper r=pyper.R() print r("library(igraph)") print r("dg<-matrix(c(0,1,0,1,0,1,0,1,1,0,0,1,0,0,0,0),nrow=4,ncol=4,byrow=TRUE)") print r("dg")
或いは、
import pyper r=pyper.R() print r(""" library(igraph) dg<-matrix(c(0,1,0,1,0,1,0,1,1,0,0,1,0,0,0,0),nrow=4,ncol=4,byrow=TRUE) dg """)
出力をそのままコピーすると以下のようになりました。
try({library(igraph)}) try({dg<-matrix(c(0,1,0,1,0,1,0,1,1,0,0,1,0,0,0,0),nrow=4,ncol=4,byrow=TRUE)}) try({dg}) [,1] [,2] [,3] [,4] [1,] 0 1 0 1 [2,] 0 1 0 1 [3,] 1 0 0 1 [4,] 0 0 0 0
pyperをimportして、r=pyper.R()でrオブジェクトを作ります。
rに引数として文字列を与えれば、その文字列そのまま、Rのターミナルへ入力したものと同じ扱いとなります。
print関数を付けるとR出力を標準出力として出せ、変数に文字列として代入することもできます。
どうもRのほうで文法ミスするとプログラムが停止しないので、一旦Rを実行できたら、そのソースコードをコピペするという使い方をしてみようと思います。
以前紹介したsqliteライブラリの扱いそっくりですね。
パイプ (コンピュータ) - Wikipedia
このpipeとpython→RをかけてPypeRということでしょうね。
逆にRからPythonを操作するrPythonライブラリもあるそうです。
Vim デザインや起動時の設定
普段はSublimeText2とVim、geditを使っています。
LinuxではSublimeText2で日本語入力ができず、geditはLaTeXで用いるものの、物足りないです。
今後はVimをより使っていこうと思っているので、設定をメモしておきます。
まずはVimのインストール
sudo apt-get install vim
また、グラフィカル版のgVimもインストールしておきます。
sudo apt-get install gvim
NeoBundleというプラグイン管理のプラグインを最初にインストールします。
git clone https://github.com/Shougo/neobundle.vim ~/.vim/bundle/neobundle.vim
set number set ruler set list set listchars=tab:>-,trail:-,nbsp:%,extends:>,precedes:<,eol:< set incsearch set hlsearch set nowrap set showmatch set whichwrap=h,l set nowrapscan set ignorecase set smartcase set hidden set history=2000 set autoindent set expandtab set tabstop=2 set shiftwidth=2 set helplang=en colorscheme desert
統計処理ソフトRとVimの連動
sudo apt-get installl tmux cd ~/.vim/bundle git clone git://github.com/vim-scripts/Vim-R-plugin git clone git://github.com/vim-scripts/Screen-vim---gnu-screentmux
更に、ホームディレクトリ下に.Rprofileという名前でファイルを作る or 追記してください。
if(interactive()){ library(colorout) library(setwidth) library(vimcom) }
gVimのデザイン関係は.vimrcではなく、.gvimrcで設定します。
colorscheme desert
Raspberry Pi 初期設定その1 ハード購入からOSの導入、起動までのまとめ
Raspberry Piとはマイコンの見かけをしているものの、Linuxを動かしうるれっきとしたパソコンです。
かわいい見た目をしていますが、Raspbianという独自のDebian系Linuxを動かすことができます。
キーボードやマウスからHDMIの接続までできるので、性能の低い普通のパソコンとして扱えます。
ただの劣化版ではなく、発熱量が小さいために、サーバーとして使ったり、ブレッドボードに接続してLED制御やら温度取得などといった器用さも持っています。
創作心のくすぐられるアイテムですね。
アクアリウムをしているので、明かりの調整や餌やりの機能を実装したいと思って買いました。
勉強中の身ですが、便利な機能を見つけ次第メモしていきたいと考えています。
まず、何はともあれ、必要器具を買いましょう。
ひと通りAmazonで買ったので、リンクを貼っておきます。
下のリンクは全てアフィリエイトになっています。
賛否両論ですが、個人的にはお金が入るのは助かりますし、値段が高くなったりはしないので、是非下のリンクから買って下さい。
これに加えて、Micro-Bコネクタ(androidの充電に使う端子)、キーボード、マウスが必要ですが、Micro-Bは持っている人が多く、キーボードとマウスはPCのものを代用すれば大丈夫です。
なお、後々紹介するssh接続やvnc接続を使えば、LAN内の別のPCからアクセスできるため、極論MicroSDカードとLANケーブルと電源のMicro-Bコネクタ以外はあまり使わなくなります。
まず、MicroSDカードにRaspbianを書き込みましょう。
Downloads | Raspberry Pi
サイズが大きいため、Torrentを使ったほうが圧倒的に早いと思われます。
念のためにSDカードをフォーマットしておきます。
上で紹介したAmazonのSDカードならば必要のない作業ですが。
Ubuntuディスクユーティリティを使います。
該当のSDカードのパーティションを全部消して、FAT32で初期化をかけます。
続いて、ダウンロードしたzipファイルを展開すると、中にimgファイルが入っていると思います。
imgファイルを右クリックしてディスクイメージライターなるものでSDカードに書き込みます。
これでRaspbianの準備は完了です。
MicroSD、HDMI、キーボードを接続して、電源を繋ぐと自動的に起動します。
青背景に英語で強面な画面がでます。
- 1 Expand Filesystemをクリックして元の画面まで戻します。
- 2 Change User Passwordではデフォルトのパスワード"raspberry"を他のものに変えられます。
- 3 Enable Boot to Desktop/Scratch 起動時にCUIの端末にするか、GUIにするか選べます。
- 4 Internationalisation Options
- 5 Enable Camera カメラモジュールを買った場合は設定?
- 6 Add to Rastrack 世界中のRaspberry Pi使いの場所が分かるとかなんとか。無視しちゃいました。。
- 7 Overclock CPUの周波数を高くすると、寿命が短くなる代わりにパフォーマンスを上げられるそうです。用途に依りそうです。
- 8 Advanced Options 面倒なので見ていません
- 9 About raspi-config 面倒なので見ていません
一通り設定すれば、Finishを選択してRebootします。
ログインのIDとパスワードを要求されます。
デフォルトでは、IDがpi、パスワードがraspberryです。
先ほど設定していれば、自分の設定したものを入れてください。
以上で端末が表示されます。
Raspberry Piが起動しおわりました!
Ubuntuと同様のLinuxの端末ですので、pythonを起動したり、viを使ったりできます。
次回、Raspberry Piの日本語化やGUIなどの環境整備について説明します。
Python zipファイルの解凍時やurllib.unquote()の日本語が文字化けする問題周辺のまとめ
Windowsで圧縮したzipファイルをUbuntuで解凍するとファイル名や子ディレクトリ名に文字化けが発生することがあります。
解決方法はたくさんあるようですが、いまいち理解できないものもありました。
ほとんどの問題は、Windowsのcp932コードを変換する際に起きている模様です。
sudo権限も必要なくて一番簡単にできた(※理解できたとは言っていない)ものをメモしておきます。
こちらのサイトのPythonコードをzipfile_altとしてzipファイルのあるディレクトリに保存して下さい。
その後、同一ディレクトリで次のコードを実行すればよいです。
import zipfile_alt as zipfile def unzip(filename, path='.', pwd=''): with zipfile.ZipFile(filename, 'r') as zip_file: try: zip_file.extractall(path=path, pwd=pwd) print 'OK' except: print 'NG' if __name__ == "__main__": unzip_with_pwd(filename="test.zip", pwd="test")
urllibのほうはもっと分かりやすいです。
#coding:utf-8 import urllib str1=urllib.quote("あいうえお") print "str1:"+str1 str2=urllib.unquote(str1) print "str2:"+str2 str3=urllib.quote(u"あいうえお".encode('cp932')) print "str3:"+str3 str4=urllib.unquote(str3) print "str4:"+str4 str5=urllib.unquote(
このときの出力は、
str1:%E3%81%82%E3%81%84%E3%81%86%E3%81%88%E3%81%8A str2:あいうえお str3:%82%A0%82%A2%82%A4%82%A6%82%A8 str4:����������
要は、unquote()関数は、utf-8を元にしたURL文字列ならばutf-8に戻してくれますが、cp932を元にしていると、cp932に戻すために文字化けが生じます。
htmlパースしているときに起こって、気づかぬまま詰まってしまったことがありました。
こういうときは当然ながら、
print "str4:"+str4.decode('cp932').encode('utf-8')
とするだけです。
Python BeautifulSoupによるxml解析
前回、
AmazonAPI Pythonによるxmlデータの取得 - 備忘録
によって、Amazonからの商品情報をxml形式で受け取りました。
今回は、xmlをSQLやcsvに保存できる程度に綺麗に変換してみようと思います。
前回のコードですが、最後の行を変更しています
#coding:utf-8 import amazon import Amazon access_key_id="" secret_access_key="" associate_tag="" amazon=Amazon(access_key_id,secret_access_key,associate_tag) xml=amazon.itemSearch("Books",Keywords=u"数学",ItemPage="1",ResponseGroup="Large") print xml
変数xmlに大量の文字情報が貯められていますが、このままでは使い物にならないため、整理したり、必要な情報だけを取り出すことをxmlパース(解析)と言います。
Pythonにはhtmlパースを行うためのライブラリ、BeautifulSoupがあって、これはxmlにもある程度実用することができますし、AmazonAPI形式ならば今のところ手の届かない処理はありませんでした。
まず、BeautifulSoupのインストールは
sudo pip install beautifulsoup
です。
では、早速著者情報を抜き取り、SQLに保存してみましょう。
#coding:utf-8 from amazon import Amazon from BeautifulSoup import BeautifulStoneSoup import sqlite3 access_key_id="AKIAI3BTABUGQXERS6FA" secret_acess_keys="tv0V27jJ+4ArXKtOzjQQbfHPdiibYlOS0qHsjZRU" associate_tag="alamz-22" con=sqlite3.connect("sample.sqlite3",isolation_level=None) sql=u""" create table IF NOT EXISTS Amazon_Books( ISBN varchar(63), author varchar(255), title varchar(255) ); """ con.execute(sql) amazon = Amazon(access_key_id, secret_acess_keys,associate_tag) xml = amazon.itemSearch("Books", Keywords=u"物理学", ItemPage="1",ResponseGroup="Large") #print amazon.url #print xml #xmlにはBeautifulStoneSoup(xml)、htmlにはBeautifulSoup(html) soup = BeautifulStoneSoup(xml) #xmlの中からitemsを見つけ出し、itemsリストにBeautifulStoneSoupクラスとして保存 items = soup.find("items") #何件あるかの結果は、xml内のtotalresultsタグにあり、その中身をcontents[0]で抜き出す。 print "%s件見つかりました" % soup.find("totalresults").contents[0].encode('utf-8') #何ページあるかの結果は、xml内のtotalpagesタグにあり、その中身をcontents[0]で抜き出す。 total_pages = soup.find("totalpages").contents[0] #xmlのitemタグ1つは、1商品の情報を囲っている。つまり、1商品の情報ごとをループ処理していく。 for item in soup.findAll("item"): print "\n\n------------------------------" ISBN=item.asin.contents[0]; author=[] if item.author==None: author.append("None") else: for i in range(len(item.author)): author.append(item.author.contents[i]) title=item.title.contents[0] author_str="" for i in author: author_str+=i.encode('utf-8')+"," author_str=author_str.rstrip(',') print ISBN,author_str,title sql=''' insert into Amazon_Books values("%s","%s","%s");''' % (ISBN.encode('utf-8'),author_str,title.encode('utf-8')) print sql con.execute(sql) con.close()
sample.sqlite3を確認すると、
***@***:~/AmazonAPI$ sqlite3 sample.sqlite3 SQLite version 3.8.2 2013-12-06 14:53:30 Enter ".help" for instructions Enter SQL statements terminated with a ";" sqlite> Select * from Amazon_Books; 4785320745|小出 昭一郎|物理学 4163757708|ウォルター ルーウィン|これが物理学だ! マサチューセッツ工科大学「感動」講義 4004200857|朝永 振一郎|物理学とは何だろうか〈上〉 (岩波新書) 4000077112|ファインマン|ファインマン物理学〈1〉力学 B009AJ8266|寺田 寅彦|物理学と感覚 4569573908|None|「量子論」を楽しむ本―ミクロの世界から宇宙まで最先端物理学が図解でわかる! (PHP文庫) 4480016007|山口 栄一|死ぬまでに学びたい5つの物理学 (筑摩選書) 4121022807|小山 慶太|入門 現代物理学 - 素粒子から宇宙までの不思議に挑む (中公新書) B00B7UNYD2|ウォルター・ルーウィン|これが物理学だ! マサチューセッツ工科大学「感動」講義 4004200865|朝永 振一郎|物理学とは何だろうか〈下〉 (岩波新書 黄版 86)
確かに保存されています。
BeautifulSoupは他にも、サイトのHTMLから情報を抜き出すときに使われたりします。
APIに対応していなくとも無理やり情報を抜き出せるという訳です。
使いこなせると便利ですので、細々とした点まで覚えておいて損はないと思います。
参考にしたサイトです。
Beautiful Soupドキュメント — BeautifulSoup Document 0.1 ドキュメント
kondou.com - Beautiful Soup 4.2.0 Doc. 日本語訳 (2013-11-19最終更新)
SQLはいわゆるリスト内にリストを保存するような構造を持てないそうです。
例えば、authorは2人、5人、0人だったりと可変ですが、事前にデータ型を決める以上一人につき一つのセルを与えることができない、という意味です。
このときのコツとして、Pythonプログラムのauthor_strの処理のように0人ならNone、複数なら','つきで加えた一つの文にする、といった手法が取れます。
注意すべき点として、例えばauthorとしてR.P.Feynmanといった変数を保存したとき、'.'区切りならば、RさんとPさんとFeynmanさんが共著したかのような解釈となります。
区切り文字はデータとして使いそうにないものを選びましょう。
AmazonAPI Pythonによるxmlデータの取得
以前Amazonのデータを取得するAPIの登録方法を紹介しました。
Amazon Product Advertising API 登録の流れ - 備忘録
今回は実際にPythonによってデータをxml形式で取得し、xmlパースを行うことによって欲しい形式に変換する手順を追ってみましょう。
AmazonAPIに登録してIDやKeyを取得すること前提ですので、先に上の登録を終えてから読んで下さい。
また、AmazonAPIはよく仕様が変わっているようですので、2015年1月以降は細部が異なる可能性があります。
さて、xmlの解析を行う前に、まずはxmlがどういう流れで得られるのか確認します。
AmazonAPIというディレクトリを作っておきます。
そこに、以下のPythonコードをamazon.pyとして保存して下さい。
これが無いと何も実践できないため先に導入しましたが、意味を解読するためには最後まで読んだ後に戻ってきたほうがよいため、ここは作業と思って下さい。
#coding:utf-8 import urllib2 import hashlib, hmac import base64 import time class Amazon: def __init__(self, access_key, secret_access_key, associate_tag=None): self.amazonurl = "http://webservices.amazon.co.jp/onca/xml" self.proxy_host = None self.proxy_port = None self.access_key = access_key self.secret_access_key = secret_access_key self.associate_tag = associate_tag self.version = "2009-10-01" self.url = None def setProxy(self, host, port=8080): self.proxy_host = host self.proxy_port = port def setVersion(self, version): self.version = version def itemLookup(self, item_id, **options): params = options params["Operation"] = "ItemLookup" params["ItemId"] = item_id return self.sendRequest(params) def itemSearch(self, search_index, **options): params = options params["Operation"] = "ItemSearch" params["SearchIndex"] = search_index return self.sendRequest(params) def buildURL(self, params): params["Service"] = "AWSECommerceService" params["AWSAccessKeyId"] = self.access_key if self.associate_tag is not None: params["AssociateTag"] = self.associate_tag params["Timestamp"] = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()) sorted_params = sorted(params.items()) request = [] for p in sorted_params: pair = "%s=%s" % (p[0], urllib2.quote(p[1].encode("utf-8"))) request.append(pair) msg = "GET\nwebservices.amazon.co.jp\n/onca/xml\n%s" % ("&".join(request)) hmac_digest = hmac.new(self.secret_access_key, msg, hashlib.sha256).digest() base64_encoded = base64.b64encode(hmac_digest) signature = urllib2.quote(base64_encoded) request.append("Signature=%s" % signature) url = self.amazonurl + "?" + "&".join(request) return url def sendRequest(self, params): self.url = self.buildURL(params) if self.proxy_host: proxy_handler = urllib2.ProxyHandler({"http":"http://%s:%s/" % (self.proxy_host, self.proxy_port)}) opener = urllib2.build_opener(proxy_handler) else: opener = urllib2.build_opener() return opener.open(self.url).read()
こちらのサイトから引用させて頂きました。
続いて、先ほどのソースコードと同じAmazonAPIディレクトリにamazon_search.pyとして次のファイルを置きます。
#coding:utf-8 import amazon import Amazon access_key_id="" secret_access_key="" associate_tag="" amazon=Amazon(access_key_id,secret_access_key,associate_tag) xml=amazon.itemSearch("Books",Keywords=u"数学",ItemPage="1",ResponseGroup="Large") print amazon.url
access_key_id、secret_access_key、associate_tagには自分のものを代入してください。
実行すると、print amazon.urlの出力としてURLが得られるはずなので、それをブラウザで見てみましょう。
xmlが確かに得られています。
amazon_search.py内の
xml=amazon.itemSearch("Books",Keywords=u"数学",ItemPage="1",ResponseGroup="Large")
という記述通り、数学に関する本を1検索分(=10冊分)、詳細なデータ(=Large)で得られています。
AmazonとPC間の情報のやりとりはたったこれだけで終わりです。
もちろん、検索の関数としてitemSearch以外にもありますし、オプションもResponseGroupの属性として山ほどあります。
ただし、これらは固有名詞的なものなので覚えてもあまり意味がないですし、Amazonの公式マニュアルを参考にしましょう。
その後はxmlパースに移ります。
区切りがよいので次回に回します。
Amazonクラスに関する説明も、仕様が変わったり、他のAPIにも応用する上では必要なので、いずれ説明する予定です。
SQLite インストールと基本操作
大きなデータを扱う機会が増えて、csvでは重かったり、手の届かない処理をしたいと思ってデータベースSQLを触ったことがあります。
SQLはcsvなどに比べて軽く、準備されている関数(SQL文)をプログラムから投げることでソートや検索のプログラムを組まなくとも結果を返してくれるなどの利点があります。
多くのサイトや企業でも採用されているようです。
一方で、多くのプログラミング言語が対応しているものの、SQLのライブラリを持っていなければ、扱うのは面倒臭いかもしれません。
その場合、SQLでとりあえずなんでも保存して、必要な部分だけcsvとして用いる、という手法が便利ですね。
PythonによるSQLの扱い方も最後に紹介します。
今回はSQLの導入と基本的な構成・操作を紹介したいと思います。(Ubuntu14.04)
まずインストールは端末で、
sudo apt-get install sqlite3
で出来ます。
続いて起動です。
sqlite3 sample.sqlite3
として、sample.sqlite3を作ってみましょう。
create table book(author varchar(50),title varchar(50),price int);
と入力してみて下さい。
ここまでで、sample.sqlite3ファイルの中に、bookというテーブルが作成されました。
bookというテーブルはauthor、priceという変数を持っていて、その変数に文字列が保存されるという仕組みです。
ここまでで、データを入れる型を作る作業ができました。
実際にデータを入れてみましょう。
insert into book values ("Richard Phillips Feynman","The Feynman Lectures on Physics",3600);
これで、Richard Phillips Feynman著、The Feynman Lectures on Physic、3600円というデータが得られた訳です。
入っているデータを確認するには、以下のように打ち込みます。
select * from book;
SQLの各種文法や関数は僕自身学んでいる途中ということで、他のサイトに任せたいと思います。
SQL文をプログラミング言語から投げて、データを保存する、といったことができます。
Pythonでの使い方を紹介します。
Pythonによってネット上からデータを取得したり、或いは実験データの数値を算出して、それをSQLに保存するといった芸当が可能になります。
この連動自体は極めて簡単ですので、SQLの文法を学ぶより先に読んでもよいと思います。
#coding:utf-8 import sqlite3 #sqlite3のデータベースに接続 con = sqlite3.connect("sample.sqlite3") #SQL文の作成 sql=u""" create table book( author varchar(50), title varchar(50), price int ); """ #sqlへ投げかける con.execute(sql) #接続の解除 con.close()
SQL文を作って、それをcon.execute(sql)によって投げかけるだけで終わりです。
データを読む操作の例として、データが登録されているか確認する関数を作ってみましょう。
まだ紹介していないSELECT文を使っていますので、読めばわかると思いますが、詳しくは調べてみて下さい。
def is_exist_author(target): sql = 'SELECT author FROM book author ="' + target + '"' cur = con.execute(sql) if len(cur.fetchall()): return True else: return False
bookテーブルのauthor属性の中に、targetというデータが含まれていた場合Trueを返し、存在しない場合はFalseを返します。
curはSQLによる出力を保存していて、fetchall()メソッドの結果が0より大きければTrue(データあり)ですね。
これを使えばデータの重複を確認することなどもできます。
以前、Amazonの書籍データを可視化した際にも実はSQLデータベースを使っていました。
そのときは、
1,PythonによってAmazonAPIからデータ取得、著者やタイトルなどをSQL文に書き直す。
2,SQLにデータを貯めこむ。
3,PythonによってSQLをcsv形式に変換する。
4,Cytoscape、R、NetworkX(Python)によって可視化させる。
という流れを取りました。