1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Python備忘録

Last updated at Posted at 2022-08-24

概要

Pythonでやった作業について,忘れないようまとめます。
※Pythonの学習中に行ったことなので、もっと便利な関数や手法があるかもしれません。

ファイルパスの操作(OSモジュールを使用)

ファイル名(拡張子付き)の取り出し

import os
fpath="aaa/bbb/ccc/ddd.png"
fname=os.path.basename(fpath)
# ddd

ファイル名(拡張子なし)の取り出し

import os
fpath="aaa/bbb/ccc/ddd.png"
fname=os.path.splitext(os.path.basename(fpath))[0]
# ddd

拡張子のみの取り出し

import os
fpath="aaa/bbb/ccc/ddd.png"
fname=os.path.splitext(os.path.basename(fpath))[1]
# .png

ディレクトリパスの取り出し

import os
fpath="aaa/bbb/ccc/ddd.png"
fname=os.path.dirname(fpath)
# aaa/bbb/ccc

ファイルパスからファイル名のみを抜き出す(OSモジュールを使用せず)

splitを使う

fpath="aaa/bbb/ccc/ddd.png"
f_split=fpath.split('/')
fname=f_split[-1]

split()で区切り文字で分割,分割した配列の最後がファイル名.
区切り文字はあらかじめ調べるor決める必要がある
参考:javascript(nodejs)でフルパスからファイル名のみを取得する方法 - Nodachisoft

正規表現を使う

import re
fpath="aaa/bbb/ccc/ddd.png"
m = re.match(r".+[\\/](.+?)([-_.]*)?$",fpath)  
print(m[1])
# ddd.png

参考:Pythonでパス文字列からファイル名・フォルダ名・拡張子を取得、結合 | note.nkmk.me

ファイル読み書きテンプレ

JSON

#.jsonの読み取り
import json
with open("test_r.json","r",encoding="utf-8") as f:
    d_read=json.load(f)
#.jsonへ書き込み
with open("test_w.json", 'w',encoding="utf-8") as f:
    json.dump(d_write, f, indent=2,ensure_ascii=False)    

保存時、indentを付けることでインデントが付き、ensure_ascii

DataFrameのよく使う?操作

NaN埋め、型変換

指定した列のみを型変換する場合

l_cols=['A','B','C']
d_rep={}
for col in ctg_columns:
    d_rep[col]=str
df=df.astpye(d_rep)

列名:型の辞書型を作成し、.astypeに指定する。
.fillnaも同じ手法でできる

l_cols=['A','B','C']
d_rep={}
for col in ctg_columns:
    d_rep[col]=0
df=df.fillna(d_rep)

df.groupbyをグループごとにfor文で回す

import pandas as pd
for idx,df_group in df.groupby(["馬番","着順"]):
    # 何かの処理
    print(idx)

正規表現の利用

正規表現で途中にある数値を取得

re.searchを使うことで文字列の途中からマッチする。

import re
fname="hogehoge24.png"
m=re.match(r"[0-9]{1,2}",fname)
print(m[0])
#24

ファイル名のパターンが決まっているなら、間の文字列を抜き出すことでも取り出せる。
「(.+)」で任意の1文字以上の文字列にマッチする。

import re
fname="hogehoge24.png"
m=re.match(r"[0-9]{1,2}",fname)
m=re.search(r"hogehoge(.+)\.png",fname) 
print(m[1])
#24

re.matchだと先頭からのマッチとなり、途中にあるパターンを抜き出せない。
参考:【python】re.match より re.search を使おう
   正規表現でファイルの拡張子を取り除く方法。

datetimeをdatetimeに変換

Javascriptから取得した時刻をPythonのdatetimeに変換する

convert_datetime.py
import re
from datetime import datetime
time_JS="2022-12-28T12:58:30+09:00"
# 年・月・日を取得
m=re.search("([0-9]{4})-([0-9]{2})-([0-9]{2})",time_JS)
# 時・分・日を取得
m2=re.search("([0-9]{2}):([0-9]{2}):([0-9]{2})",time_JS)
# Pythonのdatetimeに変換
res_datetime=datetime(int(m[1]),int(m[2]),int(m[3]),int(m2[1]),int(m2[2]),int(m2[3]))
print(res_datetime)

Excelファイルの処理

DataframeをXlsxファイルへと書き出す

複数のDataFrameをXlsxに出力するクラス

クラス内変数の辞書型配列に、Key=シート名、中身=保存したいDataFrameで登録した情報をもとにxlsxファイルを作成します。

exportXlsx.py
class exportXlsx:
    def __init__(self) -> None:
        self.dict_array={
            
        }
        pass
    def addSheet(self,item,sname):
        # シート名としてDFを保存する
        self.dict_array[sname]=item
        
    def save(self,savefpath):
        # 登録したDFを保存する
        
        dict_keys=list(self.dict_array.keys())
        # 先頭のシートで上書き
        logger.info("save:"+savefpath)
        logger.debug("save:"+dict_keys[0])
        self.dict_array[dict_keys[0]].to_excel(savefpath,index=False,sheet_name=dict_keys[0])
        # 残りのシートを追加
        with pd.ExcelWriter(savefpath, mode='a') as writer:
            for key in sorted(dict_keys[1:]):
                self.dict_array[key].to_excel(writer,index=False,sheet_name=key)
                logger.debug("save:"+key)

使い方

  1. このクラスのインスタンスを作成
  2. 保存したいDataFrameをaddSheetメソッドで追加する
    2. item:保存するDataFrame
    2. key :保存するシート名。ユニークかつ30文字以内、シート名で使えない文字を除く。
  3. すべてのDataFrameを登録したら、saveメソッドを実行。
    2. savefpath:保存するファイルパスを入れる。
main.py
import pandas as pd
import exportXlsx

df1=pd.DataFrame()
df2=pd.DataFrame()
# ~~df1,df2に中身を入れる~~
expXlsx=exportXlsx.exportXlsx()
# 保存するDataFrameの登録
expXlsx.addSheet(df1,"sheetname1")
expXlsx.addSheet(df2,"sheetname2")
# 保存
expXlsx.save("sample.xlsx")

Xlsxに色付け・線引き

DataFrameのIndex,列を指定したセルに色づけをする

def setCellColor(sheet,df,l_idx,colname,fill):
    # 指定されたセルに色を付ける
    # l_idx=df.index
    col_idx=df.columns.tolist().index(colname)
    
    for row_idx in l_idx:
        # print(row_idx,get_column_letter(col_idx))
        # excelでは行は1始まり&1行目は列名なので+2、列番号も1始まりなので+1
        sheet.cell(row=int(row_idx)+2,column=int(col_idx)+1).fill=fill
    return sheet
    
def setBorderLine(sheet,df,l_idx,border):
    # 指定されたセルに色を付ける
    
    for row_idx in l_idx:
        for col_idx in range(sheet.min_column,sheet.max_column):
            sheet.cell(row_idx+1+1,col_idx).border=border
    return sheet

GPX(xml)を処理し、座標データをDataframeにする

やったこと:StravaのGPXデータから,GoogleMapから取得した座標データと最も近い点を求め,そこを通過した時刻を出力

実装概要

  • ElementTreeによるxmlデータの読み込み
  • 緯度・経度・時刻をDataframeに格納
  • Dataframeと指定した緯度・経度を比較し最も近い値の時刻を出力

Pythonによるxmlの読み込み

xml.etree.ElementTreeという標準ライブラリを使う.
https://qiita.com/sino20023/items/0314438d397240e56576
https://pg-chain.com/python-xml-elementtree

import xml.etree.ElementTree as ET
tree = ET.parse('_3776_day1_.xml')
root = tree.getroot()
# root[0]:<metadata>,root[1]:<trk>.root[1]の2つ目?を↓で取り出す.
tree_trkseg = root[1][2]
for child in tree_trkseg:
    print(child.attrib['lat'],child.attrib['lon'],child[1].text)

このFor文によって、緯度・経度・時刻を抜き出すことができる。

必要なデータをDataframeに格納

緯度・経度・時間の3つを格納したDataframeの作成

df_cdata = pd.DataFrame(columns=['lat','lon','time'])

for child in tree_trkseg:
    # lat(緯度)lon(経度)time(時間)をデータフレームに格納
    df_cdata=df_cdata.append(pd.Series([child.attrib['lat'],child.attrib['lon'],child[1].text],index=df_cdata.columns),ignore_index=True)

1行目で空のDataframeを作成、2行目のFor文で緯度・経度・時刻の入ったpd.Seriesを作成し、1行目のDataframeにappendします。

指定した座標とマッチング

緯度・経度ともにDataframeから最も近い値をそれぞれ探し,その時刻を出力します.
こちらのサイトを参考に、入力した値から一番差が少ないDataframeの行を出力しました。
https://funmatu.wordpress.com/2018/10/01/pandas-dataframe%E5%86%85%E3%81%8B%E3%82%89%E6%9C%80%E3%82%82%E8%BF%91%E3%81%84%E5%80%A4%E3%82%92%E6%8E%A2%E3%81%99/

l_lat = df['lat'].sub(SEARCHLAT).abs().argsort()[:5]
l_lon = df['lon'].sub(SEARCHLON).abs().argsort()[:5]
for i in l_lat:
    print(i,df['time'][i])
print("===============================")
for i in l_lon:
    print(i,df['time'][i])

緯度・経度で別々の行が出力されるため,近い順に5行の時刻を出力した後、最も近い(と思われる)値を参考にしました。

1
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?