【メモ】XMLパース方法

xml

個人的備忘録として、XMLのファイルを元にパースメモを記します。 document

<?xml version="1.0"?>
<data>
    <country name="Liechtenstein">
        <rank>1</rank>
        <year>2008</year>
        <gdppc>141100</gdppc>
        <neighbor name="Austria" direction="E"/>
        <neighbor name="Switzerland" direction="W"/>
    </country>
    <country name="Singapore">
        <rank>4</rank>
        <year>2011</year>
        <gdppc>59900</gdppc>
        <neighbor name="Malaysia" direction="N"/>
    </country>
    <country name="Panama">
        <rank>68</rank>
        <year>2011</year>
        <gdppc>13600</gdppc>
        <neighbor name="Costa Rica" direction="W"/>
        <neighbor name="Colombia" direction="E"/>
    </country>
</data>

XMLファイル読み方

一行目 <?xml version="1.0"?>の箇所は「そのテキストが XML であることを示すための宣言」です。 パースする際には無視して構わない。

二行目 <data>は一番の要素であり、XML構造データの始まりを示している。       ルートディレクトリと呼ばれる。

三行目 <country>の入れ子状態となっており、子要素と呼ばれる。       からみた場合、親要素と呼ばれる。       

parse方法

from xml.etree import ElementTree

x = 'sample.xml'               # 読み込むxmlファイルのパスを変数に記憶させる
tree = ElementTree.parse(x)    # xmlファイルを読み込む
# print(tree)
root = tree.getroot()          # ルートを取得する


print(tree.findall('country'))
print(root[0][0].tag)
print(root[0][0].text)
# xpath *→直接の子要素 .→現在の要素
//→現在の要素配下のすべてのレベル上のすべての子要素を選択

print(tree.findall("*/rank"))
print(tree.findall(".//*[@name='Singapore']"))
print(tree.findall(".//"))
for child in root:
    print(child.tag, child.attrib)

メソッド(使いそうなところだけ)

  • ElementTree.parse … xmlを読み込む
  • findall … 現在の要素の直接の子要素を取得  この場合、xmlを読み込んだ際はルートディレクトリから始まるので子要素はcountryタグとなる。
  • 指定している要素からさらに子要素をみたい時は「*」を用いる。
  • インデックス 移動する位置が面倒な場合は[i]が使える。(i:0,1…)  一個つけると、隣接した子要素のi番目の要素を指定
  • 指定したnodeに複数のタグがあり、絞りたい場合は「/タグ名」で絞る。

タグの情報取得

  • タグ名を表示したい場合は、指定したタグに「tag」をつける。
  • 属性名を表示したい場合は、「attrb」をつける
  • テキストを表示したいときは 「text」をつける

メモ xmlint

今度使ってみる。

TravisCI入門しました!

はじめに

Travis CIを利用し始めたので、 備忘録も兼ねてブログに書き込んでおきます。

利点

Travis CIを使うことによる利点は、

  • TravisCI側サーバーで設定した環境でテスト
  • テスト結果をメールなどで開発メンバーに通知
  • 連携しているホスティングサービスにデプロイ(AWSなど)

となります。

実行の流れ

具体的にTravis CIの設定〜実行の流れを書き下すと、以下の通りとなります。

  1. TravisCI登録し、指定したGithubのレポジトリ連携
  2. 連携したフォルダにTravisCI用に設定ファイルを作成
  3. githubにプッシュすると、設定した環境に応じてTravisCIがテスト実行
  4. テスト結果に応じて処理

1. についてはTravis CIはGUIが非常に素晴らしく、簡単なので割愛します!

TravisCI用設定ファイル作成

連携したレポジトリのルートディレクトリに以下のようなYAMLファイルを作成します。

language: python
python:
  - "3.5"
install:
  - pip install <パッケージ名>
script:
  - python py_test.py
after_success:
  - <slack通知>
  • python: はテストするプログラミング言語install:はインストールするパッケージを指定します 注)
  • scriptは実際のテストを行なう作業を記述します。今回は指定したファイルを実行します。
  • after_successとはテスト成功した後の処理を指します。今回はslack通知を記述しておきました。

注)今回はpython標準ツールを使っているので、本来はinstallの必要はありません。

testスクリプト

今回はunittestを用いて以下のように書いてみました!

import unittest 

class PyTest(unittest.TestCase):
    
    def test_equal(self):
        one = 1
        self.assertEqual(one,1, "one is 1")
    
    def test_not_equal(self):
        two = 2
        self.assertNotEqual(two,3,"2 not equal 3")
        
    def test_almost_equal(self):
        three = 3.1
        self.assertAlmostEqual(three,3,0,"3.1 almost equal 3")
    
    def test_assert_regex(self):
        sentence = "test作業はつまらない。じゃなくて、楽しいぞ〜"
        self.assertRegex(sentence,'test.+楽.{1,}〜$',"test作業:マッチ")
        
if __name__ == "__main__":
    unittest.main()

プッシュ後

連携したレポジトリをGithubにプッシュすると自動で指定したテスト (今回はpy_test.py)が実行されます。

テスト結果は以下のようにGUIで表示され、非常にわかりやすいです!

https://gyazo.com/9e1a250d7aacdfe0e96152cd57e847b4

テスト成功後

https://gyazo.com/da190212686c604753d973c3186c13b0

テストが成功したので自動でスラックに投稿されています。(.travis.ymlで記述) チーム開発している時にはテスト結果をいちいち通知を手動で書く必要がなく便利です。

Tensorflow で OLS(最小二乗法) ~その1~

はじめに

先日、Google社製のライブラリTensorflowを使ってみました。 備忘録も兼ねてブログにまとめていきます。

本ブログでは、スクレイピングした賃貸情報データを元に 家賃(非説明変数)と他の情報(説明変数)を用いて回帰分析を行います。

分析対象データ(物件情報)

取得データ変数(抜粋)

家賃 専有面積 管理費 礼金 最寄り駅から
の距離
建築年数 建築材
万円 m2 万円 徒歩N分 N年 木造・鉄筋・鉄骨

具体例(抜粋)

スクレイピングデータはこんな感じです。 https://gyazo.com/2a9e3a35f878d855048bf838d4cac83a

今回分析すること

家賃を非説明変数として、取得したスクレイピングデータを元に 賃料(=家賃+管理費+礼金/24)をどれだけ説明出来るか分析してみます。

今回は前段階としてざっくりと家賃(Y軸)と説明変数候補(X軸)をプロットしてみます。

X軸(建築年数)

https://gyazo.com/97f74a310832f1b476d048def62669fc

X軸(専有面積m2)

https://gyazo.com/37d297ef7c107a05d0d1eaba4fa8cff6

X軸(徒歩分数)

https://gyazo.com/1d4f5d3028e42dd34ea60e90f2834ed1

プロットしてみた感じだと、

  • 建築年数は賃料と負の相関
  • 専有面積は賃料と正の相関
  • 最寄り駅からの近さと賃料からは相関は微妙

といった傾向が見えます

次回、賃料に対して上記3つの変数がどの程度影響与えているのか最小二乗法を使ってみます。

【linuxメモ】 cat sed

説明の前提、カレントディレクトリに以下のファイルがあるとする。

hoge1
hoge2
hoge3

cat

  • 定義 ファイル内容を標準出力に表示
$ cat hoge.txt
hoge1
hoge2
hoge3

と出力される。

-nをつけると、行番号が表示される。

$ cat -n hoge.txt
1   hoge1
2   hoge2
3   hoge2

sed

  • 定義 文字列の置換、行の削除を行なう。
  • オプション 「i」ファイルを直接編集、「e」スクリプトを実行

置換

eオプションに続いてスクリプト「s/置換前/置換後/」を用いると置換出来る。

# 末尾にgをつけると全て置換、数値の場合はマッチした番号を置換
# 全行で置き換えを実施 テキスト文にある test→hoge
$ sed -ie "s/test/hoge/g" hoge.txt

# 正規表現も使える。
$ sed -ie "s/./tttt/g" hoge.txt
$ sed -ie "s/^hoge$/test/g" hoge.txt

 削除

#1行目を削除
$ sed '1d' hoge.txt
#1~3行目を削除
$ sed '1,3d' hoge.txt

リダイレクトすれば、勿論新規ファイル作成も出来る。

# hoge → test 置き換えファイル作成
$ sed -e "s/hoge/test/g" > test2.txt

【Pythonメモ】zip

zip

複数のシーケンスを並列的に反復処理が出来る。

list1 = [1, 2, 3] list2 = [4, 5, 6] for (a, b) in zip(list1, list2): #list1,list2を同時にループ … print(a,b)

>> list1 = [1, 2, 3]
>> list2 = [4, 5, 6]

for (a, b) in zip(list1, list2): 
    print(a,b)

1 4
2 5
3 6
#シーケンスの要素数が異なる場合、要素数が少ない場合に合わせて挙動

>> list1 = [1, 2, 3,4]
>> list2 = [4, 5, 6]

for (a, b) in zip(list1, list2): 
    print(a,b)

1 4
2 5
3 6

【Pythonメモ】enumerate OrderDicts nditer

enumerate

リストをインデックス化することができます。

>> list=["a","b","c","d","e"]
>>> for index,val in enumerate(list):
        print(index,val)

(0, 'a')
(1, 'b')
(2, 'c')
(3, 'd')
(4, 'e')

OrderDicts

ディクショナリとほぼ同じだが、順序が保存出来る。

>>> tests = OrderedDict()
>>> tests['test1'] = '1'
>>> tests['test2'] = '2'
>>> tests['test3'] = '3'
>>> print tests
OrderedDict([('test1', '1'), ('test2', '2'), ('test3', '3')])

>>> for k, v in fruits.items():
        print(k,v)
 
('test1', '1')
('test2', '1')
('test3', '2')

numpy nditer

nditerを用いると、繰り返し処理が楽なる

例えば、2×3行列なら以下のように×

import numpy as np

np_array = np.random.randn(2,3)

print(np_array)

nditer = np.nditer(np_array, flags=['multi_index'])

while not nditer.finished:
    print(np_array[nditer.multi_index])
    nditer.iternext()
    
[[-1.10258502 -1.390158   -1.3459963 ]
 [ 0.92886904 -0.2251729   0.23059408]]

-1.10258502292
-1.39015799755
-1.3459963044
0.928869035018
-0.225172899317
0.230594077137

pythonのみで同じ処理を書くのは以下の通り

ネストしなくていい分、nditerを使ったほうが楽です。

for  test in np_array:
    for t in test:
        print(t)

【pythonメモ】numpyメソッド randn max sum

random randn

標準正規分布を出力(標準0、分散1)

import numpy as np

>>> np.random.randn() 
#-0.728737781876976
>>> np.random.randn(2,3) #2×3
array([[-0.01827125, -0.38984807,  0.08674773],
       [ 0.68593183,  0.82708901, -0.15050036]])

max

配列の中の最大値を出力

>>> np.random.randn(2).max()
2

sum(axis)

>>> np.array([1,2]).sum()
3