[Python] 270 CSVファイルの重複行削除

メモ書きしておきます。

for path in paths:
    df = pd.read_csv(path,header=None,encoding='shift_jis')

    # 列0の値が重複する場合に最初の行だけ残す
    df2 = df.drop_duplicates(subset=[0])

    with open(path,mode="w",encoding="cp932", errors="ignore") as f:
        df2.to_csv(f,index=False,header=False)

[Python] 269 欠番リスト作成(差集合)

リスト同士を比較して差分を演算するコードの一例です。

千番単位で連番リストを作り、比較したいリストとの差集合を演算します。

# 連番リスト作成
list_num = [[str(x).zfill(5) for x in range(1000*thou +1,1000*thou +1001)] for thou in range(0,11) ]

# 比較リスト作成
list_compare_pre = glob.glob('/*.csv')
list_compare = [path.split('.')[0][-5:] for path in list_compare_pre]

# 欠番リスト作成    
list_lack = list(set(list_num[0]) - set(list_compare))
list_lack.sort()

[Python] 268 ゼロ埋め数字のリストを作成する その2

前回の続きです。

for文ではなくリスト内包表記で書くと以下の通りになります。

リストを関数の戻り値にすることもできますが、普通に変数にする方が使い勝手は良さそうです。

# 00001から11000までの千番台ごとのリストを入れ子にしたリストを作成する関数
def list_num():
    return [[str(x).zfill(5) for x in range(1000*thou +1,1000*thou +1001)]\
for thou in range(0,11) ]

list_num_flat = [y for x in list_num() for y in x]

print(len(list_num_flat))
--------------------------------------------------

出力
--------------------------------------------------
11000

[Python] 267 ゼロ埋め数字のリストを作成する

00001から11000のゼロ埋め数字を1000個ずつまとめたリストの作成コードです。欠番検索の元データに使えます。

リスト内の1つ目のリストは00001から01000のゼロ埋め数字で構成されています。

list_all = list()
for thousand in range(0,11,1):
    list_thou = list()
    for num in range(1,1001,1):
        number = 1000*thousand + num
        # 数字を5桁のゼロ埋め数字に変換する
        number_5digits = str(number).zfill(5)
        list_thou.append(number_5digits)
    list_all.append(list_thou)

# リストを平滑化して入れ子をなくす
list_all_flat = [y for x in list_all for y in x]

print(len(list_all_flat))
--------------------------------------------------

出力
--------------------------------------------------
11000

[Python] 266 globによるパス一覧からの選別

久しぶりにPythonをいじりました。最近は融通の効かないJavaを使いこなすことにやりがいを感じていましたが、Pythonの自由さもいいものです。

globメソッドで得られたCSVファイルのパス一覧から、ファイル内容が条件に合致するパスのリストを作成しようとしたところ、エラーになってしまう問題にぶつかりました。さすがにそこまで柔軟ではないようです。

仕方ないのでパスをprint関数でtxtファイルに追記出力しました。

# 競走馬個別ファイル内の競走馬名が幼名("XXXの2018"など)になっているファイルのパスリストを作成
import glob,os,re,sys
import pandas as pd

print("検索する年度を入力してください")
year = input()

path = f'/horse/{year}'
print(os.listdir(path))

# 数字が含まれているディレクトリ名をリスト化する
pattern = r'\d'
list_dir = [p for p in os.listdir(path) if re.compile(pattern).search(p)]
print(list_dir)

for dir in list_dir:
    for path in glob.glob(f'/horse/{year}/{dir}/*.csv'):
        df = pd.read_csv(path,header = None,encoding='shift_jis')
        
        # B1セル相当の文字列に数字が含まれている場合、ファイルパスを追記出力する
        if re.compile(pattern).search(df.iat[0,1]):
            print(df.iat[0,1])
            with open('未登録馬path.txt', 'a') as f:
                print(path, file = f)
                # list.append(path)は不可なのでこのような処理になった

[Python] 265 日付・時刻の文字列化関数

前回記事の続きです。

日付・時刻の文字列化コードは使用頻度がかなり高いため関数にしました。

import datetime

datetime_now = datetime.datetime.now()

def now():
    datetime_now_str = datetime_now.strftime('%y%m%d%H%M')
    return datetime_now_str

def today():
    datetime_today_str = datetime_now.strftime('%y%m%d')
    return datetime_today_str
from my_library import date

print(date.now())
print(date.today())
--------------------------------------------------

出力
--------------------------------------------------
2106081330
210608

[Python] 264 日付・時刻の文字列化

ファイル名に今日の日付や現在時刻を付ける場合の文字列作成コードです。

import datetime

datetime_now = datetime.datetime.now()
datetime_now_str = datetime_now.strftime('%y%m%d%H%M')
datetime_today_str = datetime_now.strftime('%y%m%d')

filename_now = f"/{datetime_now_str}.csv"
filename_today = f"/{datetime_today_str}.csv"

print(filename_now)
print(filename_today)
--------------------------------------------------

出力
--------------------------------------------------
/2106080730.csv
/210608.csv

[Python] 263 C言語でモジュールを作成

[macOS Catalina 10.15.7]

これまで自作モジュールはPythonで書いてきましたが、高速化が必要な場合にC/C++モジュールで対応するためテストしてみました。

1.C言語モジュールの作成

#include <Python.h>

static PyObject* 
hello_world (PyObject *self, PyObject *args) {
  printf("Hello_world\n");
  Py_RETURN_NONE;
}

// メソッドの定義
static PyMethodDef TestMethods[] = {
  {"hello_world", (PyCFunction)hello_world, METH_NOARGS, "test1: hello_world"},
  {NULL, NULL, 0, NULL}
};

// モジュールの定義
static struct PyModuleDef testmodule = {
  PyModuleDef_HEAD_INIT,
  "test",
  NULL,
  -1,
  TestMethods
};

// メソッドの初期化
PyMODINIT_FUNC PyInit_test (void) {
  return PyModule_Create(&testmodule);
}

2.setup.pyの作成

from distutils.core import setup, Extension
setup(name='test',
        version='1.0',
        ext_modules=[Extension('test', ['test.c'])]
)

3.C言語モジュールのビルド

python setup.py build_ext -i

4.C言語モジュールの動作チェック

作成されたtest.cpython-39-darwin.soファイルをあらかじめ用意しておいたc_moduleフォルダへコピーし、以下のコードを実行。

c_moduleフォルダをライブラリとして認識させるため、フォルダ内に空の__init__.pyを置くようにする。

そしてc_moduleフォルダまたはシンボリックリンクをこのコードと同じところに置く。

なお今後のためにc_moduleフォルダを作成しましたが、soファイルをソースコードと同じところに置くだけでも1行目”import test”にて実行可能です。

from c_module import test

test.hello_world()
--------------------------------------------------

出力
--------------------------------------------------
Hello_world

参考サイト

[Python] 262 subprocessモジュール2 日付を出力 続編

[macOS Catalina 10.15.7]

前記事でBashにて3日後の日付を出力させるのに苦労しましたが、仕切り直しで再調査したところあっさり解決しました。

info dateコマンドで出力されるドキュメントが参考になりました。やはり分からなければ開発元のドキュメントを読むのが基本ですね。

UNIXのタイプによってルールが全く異なるというのがよく分かりました。ちなみにmacOSはBSDベースです。

import subprocess
from subprocess import PIPE

# 3日後の場合 Bash
com_date_3 = subprocess.run("date -v+3d +%y%m%d", shell=True, stdout=PIPE, stderr=PIPE, text=True)
date_3 = com_date_3.stdout

print(f'date_3 {date_3}')
--------------------------------------------------

出力
--------------------------------------------------
date_3 210531