さわやかに

Pythonのことだったり子供のことだったり

Python Pandas DataFrame 便利なApply

import pandas as pd
df_fruit = pd.DataFrame({'フルーツ': ['りんご', 'ばなな', 'ぶどう', 'みかん', 'もも', 'なし','すいか', 'メロン', 'パイナップル', 'かき'],
                        '価格': [50, 100, 500, 30, 400, 200, 1000, 2000, 300, 80]})
f:id:kinakobanana:20201002232505p:plain
df_fruit

価格をもとに新たな価格指数カラムを作る
条件は500円以下をLow、500円を超え1000円以下をMid、1000円を超えるものをHighとする

df judge(ex):
    if ex <= 500:
        return 'Low'
    elif 500 < ex <= 1000:
        return 'Mid'
    else:
        return 'High'
df_fruit.loc[:, '価格指数'] = df_fruit.loc[:, '価格'].apply(judge)
f:id:kinakobanana:20201002235205p:plain
df_fruit

できました



価格指数に入力されている['Low', 'Mid'. 'High']のデータを、3カラムに分類し該当箇所には1を、非該当箇所には0を入れたDataFrameを作成する

df_price = pd.get_dummies(df_fruit.loc[:, '価格指数'], prefix='価格')
f:id:kinakobanana:20201003000005p:plain
df_price

できました

Pythonによるあたらしいデータ分析の教科書」を参考にさせてもらいました。

Python pandas Excelファイル 複数シートの読み込み

sample.xlsxにはSheet1とSheet2の2シートが存在し、この2つのシートからpandasのDataFrameデータとして読み込む

f:id:kinakobanana:20200910122802p:plain
sample.xlsxのSheet1
f:id:kinakobanana:20200910122855p:plain
sample.xlsxのSheet2

sheet_nameにシート名をリストで複数指定すると辞書型で格納される
dfには辞書型なので、df['Sheet1']と出力する

import pandas as pd
df = pd.read_excel('sample.xlsx', sheet_name=['Sheet1', 'Sheet2'])
df['Sheet1']

デフォルトでは1行目をヘッダー、2行目以降をデータとして読み込んでいくので、
今回のsample.xlsxのSheet1は3行目までの空白行を範囲外とする必要がある
f:id:kinakobanana:20200910230047p:plain

読み飛ばしたい行はskiprowsに指定すると範囲外になる

  • skiprows=3とすると1〜3行目を読み飛ばす
  • skiprows=[1, 3]とすると1行目と3行目を読み飛ばす

ヘッダーが2行分ある場合はheader=[0,1]と指定をする

import pandas as pd
df = pd.read_excel('sample.xlsx', sheet_name='Sheet1', skiprows=3, header=[0, 1])
df

f:id:kinakobanana:20200910232434p:plain
大丈夫そうです


Sheet1とSheet2でskiprowsやheaderの指定が異なるので2度こうなる・・・けど

df1 = pd.read_excel('sample.xlsx', sheet_name='Sheet1', skiprows=3, header=[0, 1])
df2 = pd.read_excel('sample.xlsx', sheet_name='Sheet2')

これでいいんか?
もう少しスマートな書き方はないのかなと調べたら、コチラ
www.google.com
こうなりました。

xls = pd.ExcelFile('sample.xlsx')
df1 = pd.read_excel(xls, sheet_name = 'Sheet1', skiprows = 3, header = [0,1])
df2 = pd.read_excel(xls, sheet_name = 'Sheet2')
df1
df2
f:id:kinakobanana:20200910233745p:plain
Sheet1から読み込んだdf1
f:id:kinakobanana:20200910233837p:plain
Sheet2から読み込んだdf2
終わりです

Python コーディング規制

PEP8

コーディング規制が定められているもの
ペップエイトと呼ぶ

  • インデントはスペース4つとしてタブは使わない
  • 79文字以下で行を折り返す
  • 可能であればコメント行は独立させる
  • docstringを使う
  • 演算子の周囲やカンマの後ろにはスペースを入れるが、カッコのすぐ内側には入れない
    例) a = f(1, 2) + g(3, 4)
  • クラスにはCamelCase(単語の頭文字を大文字にして接続するスタイル)
  • 関数やメソッドにはlower_case_with_underscores(小文字の単語同士をアンダースコアで繋ぐ)
  • メソッドの第一引数としては常にselfを使うようにする

PEP8に違反していないか調べる

pycodestyleをつかう

仮想環境(venv-test)で実行
sample.pyには「import sys, os」と入力してある
PEP8によれば、別のモジュールをインポートする時は1行ずつインポートするべき

python -m venv venv-test
venv-test/scripts/activate
(venv-test)> pip install pycodestyle
(venv-test)> pycodestyle sample.py
sample.py:1:11: E401 multiple imports on one line # 1行に複数のインポート
sample.py:1:15: W292 no newline at end of file      # ファイルの終わりに改行なし

使用していないモジュールや変数をチェックする

Flake8(フレークエイト)をつかう

(venv-test)> pip install flake8
(venv-test)> flake8 sample.py
sample.py:1:1: F401 'sys' imported but unused       # 'sys'はインポートされましたが使用されていません
sample.py:1:1: F401 'os' imported but unused        # 'os'はインポートされましたが使用されていません
sample.py:1:11: E401 multiple imports on one line # 1行に複数のインポート
sample.py:1:15: W292 no newline at end of file      # ファイルの終わりに改行なし

Python 文字列操作

文字列の分割

s1 = 'apple,orange,peach'
s1.split(',')
# output -> ['apple', 'orange', 'peach']

文字列の結合

s2 = ['apple', 'orange', 'peach']
'\n'.join(s2)
# output -> 'apple\norange\npeach'

左右の空白の削除

s3 = ' apple '
s3.strip() # 左右
# output -> 'apple'
s3.rstrip() # 右
# output -> ' apple'
s3.lstrip() # 左
# output -> 'apple '

末尾のチェック

ファイルの拡張子確認などに

s4 = 'sample.jpg'
s4.endswith(('jpg', 'gif', 'png')) #リストはダメ。タプルで指定
# output -> True

Google Chromeのディベロッパーツールの使い方メモ

PythonのRequestsを使い、ログイン認証が必要なWebスクレイピングをしたい。

サイトのヘッダーにログインボタンがあり、ダイアログがでてくる仕様になっているサイト。
Chrome上で「F12」ボタン押下しディベロッパーツールを開く。
ElementsパネルでHTMLを見てログインのformを確認してみた。

<div id="login-form" class="modal fade" role="dialog" tabindex="-1">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <span>ログイン</span>
                <button type="button" class="close" data-dismiss="modal">× 閉じる</button>
            </div>
            <div class="modal-body">
                <form class="form-horizontal">
                    <div class="fl-form-line form-group">
                        <label for="email" class="require">メールアドレス/<br>ログインID</label>
                        <div class="fl-form pb20">
                            <input type="text" class="form-control" id="email" placeholder="メールアドレスを入力してください" autocomplete="username">
                        </div>
                    </div>
                    <div class="fl-form-line form-group">
                        <label for="password" class="require">パスワード</label>
                        <div class="fl-form pb20">
                            <input type="password" class="form-control" id="password" placeholder="パスワードを入力してください" autocomplete="current-password">
                            <div class="checkbox pt0">
                                <label>
                                    <input type="checkbox" class="pwd-toggle" data-target="password">
                                    <span>パスワードを表示する</span>
                                </label>
                            </div>
                        </div>
                    </div>
                    <div class="form-group right mr10 font13">
                        <a href="/user/forgotpwd">パスワードを忘れた方はこちら</a>
                    </div>
                    <div class="form-group center mt30">
                        <button type="button" class="btn btn-fl-sm btn-fl-cancel arrow-left-white" data-dismiss="modal">
                            <span class="pr20 pl30">キャンセル</span>
                        </button>
                        <button type="submit" class="btn btn-fl-sm btn-fl-submit arrow-right-white">
                            <span class="pr50 pl40">ログイン</span>
                        </button>
                    </div>
                </form>
            </div>
            <div class="modal-footer">
                <div>SNSでログイン</div>
                <div class="mb10">
                    <button class="link social-button facebook" data-url="/sns/login/facebook" data-ga-cat="User" data-ga-act="Login" data-ga-opt="Facebook">
                        <span>facebook</span>
                    </button>
                    <button class="link social-button twitter" data-url="/sns/login/twitter" data-ga-cat="User" data-ga-act="Login" data-ga-opt="Twitter">
                        <span>twitter</span>
                    </button>
                </div>
            </div>
        </div>
    </div>
</div>

ログイン認証の方法について調べると、formからPOSTする要素のname属性やvalue属性を探せばいいみたいだが。。。
ありませんね。。。



ってことで実際に通信を確認しよう。
Networkタグをクリックして開く
Networkタグを開いたままログインしてみる
f:id:h_267_sunny:20200805005239j:plain
一瞬「Name」のところに「login」が見えたがどっかいったー
フィルターで「login」を探したがヒットしない
ページ移管したことでクリアされてしまったようだ




ログを保存しておける「Preserve log」にチェックをいれておけば消えないらしい
再度ログイン・・・
「login」見つかりました!

f:id:h_267_sunny:20200805002000j:plain
ディベロッパーツール2

Headersタグを見て「Form Data」にPOSTされたデータが見つかった
ユーザがinputするメールアドレスとパスワード以外はPOSTされるデータがないことが分かった

f:id:h_267_sunny:20200805003333j:plain
ディベロッパーツール3

あと、参考に。
ダイアログでのログインformだったのでrequestsのPOSTするurlはホームにしていたらエラーになったのでなんでかと思ったら
https://…/login」だったらしい。
これはカーソルをのせたらURLがでてきて判明したのでメモ書き。

f:id:h_267_sunny:20200805004328j:plain
ディベロッパーツール4


とりあえず以上

おすすめの100均 母子手帳ケース

つい先日母子手帳ケースを変えました。

妊娠中は「ザ・母子手帳ケース!」というようなデカ目なケースを使っていましたが、

子供が産まれてからの外出はとにかく荷物が多い!



嵩張る母子手帳ケースはやめて、
小さいケースに買い換えよう、、、
と決めました。

 

私の母子手帳のサイズはMサイズでB6になります。

ちなみに、世の中の母子手帳はS・M・Lの3つの大きさがあるそうです。
Sサイズの市町村が多いみたいですね。

うちの所も小さいと良かったんですけど。。。

一応まとめました。

種類 用紙
サイズ
縦×横
(cm)
同サイズ
S A6 14.8×10.5 お薬手帳
パスポート
文庫本
M B6 18.2×12.8 卓上カレンダー
単行本
L A5 21.0×14.8 文芸春秋
コロコロコミック


そして、私が買ったのは
ダイソーのWファスナービニールネットケースです。

いろいろ調べたり探したりした結果
まさかの100円均一に落ち着きました笑

 

でも結構気に入っています!

ぴったりジャストサイズです!

気になる出し入れのし易さ

まあまあです

保険証、医療証、検診の補助券は別ポケットに分けたいのでサブポケットは必須です
手前の小さいポケットにぴったり入りました!
本体は網目模様がありますがサブポケットは透明なので中身が丸見えで何枚か診察券を入れても探しやすいです

全体が白で黒のDカンが付いているのがいいです

素敵な買い物ができました

ExcelVBA データの並べ替え

f:id:kinakobanana:20211023235354j:plain

Sortオブジェクト

Excel2007以降の難しいSort
「並べ替え条件の指定」と「並べ替えの挙動」の2つに大きく分かれる

1. 並べ替え条件の指定

シート.Sort.SortFields.Add2 Key:=基準(Range型), _
         SortOn:=セルの値かセルの色か文字色か条件付き書式か, _
         Order:=昇順か降順か, _
         CustomOrder:=ユーザ設定の並べ替え順序しようするか, _
         DataOption:=数値と文字列を別々に並べ替えるか文字列を数字とみなすか, _
         SubField:=データ型に対して並べ替えるフィールドを指定

【SortOn引数】

定数 意味 既定値
xlSortOnValues セルの値
xlSortOnCellColor セルの背景色  
xlSortOnFontColor 文字色  
xlSortOnIcon 条件付き書式のアイコン  

【Order引数】

定数 意味 既定値
xlAscending 昇順
xlDescending 降順  

【DataOption引数】

定数 意味 既定値
xlSortNormal 数値と文字列を別々に並べ替える
xlSortTextAsNumbers 文字列を数値として並べ替える  

必ず指定しなければならない引数はKeyのみ

2. 並べ替えの挙動

With シート.Sort
 .SetRange セル範囲(Range型)
 .Header = ヘッダーを含むか
 .MatchCase = 小文字大文字を区別するか
 .Orientation = 行方向か列方向か
 .SortMethod = ふりがなか文字コードか
 .Apply '並べ替え実行
End With

【Headerプロパティ】

定数 意味 既定値
xlGuess 自動判定
xlYes 1行目(1列目)はタイトル  
xlNo タイトルを含まない  

【MatchCaseプロパティ】
 大文字と小文字を区別する場合はTrue
 区別しない場合はFalse

【Orientationプロパティ】

定数 意味 既定値
xlTopToBottom 行方向に並べ替え
xlLeftToRight 列方向に並べ替え  

【SortMethodプロパティ】

定数 意味 既定値
xlPinYin ふりがなで並べ替え
xlStroke 文字コードで並べ替え  

Excel上の画面では次の通り
f:id:h_267_sunny:20200402003604j:plain
f:id:h_267_sunny:20200402012827j:plain
【例】

With Worksheets("Sheet1").Sort
 .SortFields.Clear
 .SortFields.Add2 Key:=Range("C1"), Order:=xlDescending
 .SetRange Range("A1:D10")
 .Header = xlYes
 .MatchCase = False
 .Orientation = xlTopToBottom
 .SortMethod = xlPinYin
 .Apply
End With

Sortメソッド

Excel2003以前の簡単なSort

セル範囲.Sort Key1:=基準(Range型), Order1:=昇順か降順か, Header:=ヘッダーを含むか

「Key」と「Order」は1~3まで指定できる
その他、「MatchCase」、「Orientation]、「SortMethod」などの引数がある

次のコードはA1セルを含む表全体を並べ替える

Range(”A1”).Sort Key1:=Range("D1"), Order1:=Ascending, Header:=xlYes