- weekday(date):MySQLから日付を曜日番号で取得する。
- 休日で東証休場だと期間内の曜日減る:合計値を求めて気が付いた。
- 曜日ごとに[合計 / 出現回数]で平均を求めた。
- 曜日数をfor文ループに使い、リスト添え字、作り出す辞書型キーにも、値添え字にも使い…。
本日も、株価データ集計の悩みをMicrosoft:Copilotに助けてもらい、解決できました。
曜日別に株価の平均を得るには、期間内の曜日ごとの合計値(例えば「始値」)と同曜日回数が必要です。データがリスト内辞書型二次元データでしたので悩みましたが、Copilotはスラスラと教えてくれました。

weekday(date):MySQLから日付を曜日番号で取得する。
「N曜日は損する」などというのが気になりました。まずは、曜日別のデータを用意する必要があります。MySQLからデータ取り出すとき、「SELECT weekday(date) FROM テーブル名」などとすると、日付が曜日数になってくれます。
爺の場合、0:月曜~4:金曜で使っています。
当然、曜日を取り出しただけでは足りず、検証する数値が必要です。今回、[前場高値]ー[前場始値]でデータ取得しました。
休日で東証休場だと期間内の曜日減る:合計値を求めて気が付いた。
0~4ということで、普段は、5市場日@週当たりという計算になりますが、休日で東証休場になると、単純に合計を求め、定数で割るのは不都合です。また、期間が5の倍数日でないのも定数で割り算するには塩梅が悪いです。
そこで爺は、「よくわからん」ということでCopilotに助けてもらいました。
最初は、辞書型の合計を求める質問
当初の質問は単純に曜日別合計値を求める内容でした。
ここで教えてもらったのが
from collections import defaultdict (略) aggregated = defaultdict(float)
という書き方でした。これにより、辞書で空値などがあってもエラーにならないのだそうです。
ここまでが、昨日の出来事でした。
朝になって、「市場が休みだったら、合計に影響するよな~」と思った(現実にあったことだけど)
目が覚めて気になりました。この項の見出しの通り出現回数が曜日によって異なるので「合計」だけでは単純に比較できない可能性があります。現実に期間内に起こったコトですから「無視」「外れ値」などもできません。さて、どうしたものか…。
曜日ごとに[合計 / 出現回数]で平均を求めた。
前日、collectionsで合計の出し方を教えてもらったついでに、他の使い道を教えてもらってました。次のようなことでした。
集計 → defaultdict
カウント → Counter
順序保持 → OrderedDict
双方向リスト操作 → deque
名前付き構造 → namedtuple
出典:Copilot
「カウント」が目にとまりました。[合計 / 出現回数] 計算[出現回数]を求めることができそうです。それで、爺、自分で調べました。結果、曜日別の出現回数を得ることができました。
しかし、出現回数は曜日別に並んでませんでした(ソート未済)。合計値も曜日によるソート未済の状態のもありました。どれとどれの組合せが合理的かCopilotに尋ねたら、カクカク・シカジカだと教えてくれました。
合理的な内包表記の方法も教えてもらいました。次に、スクリプト掲載します。
曜日数をfor文ループに使い、リスト添え字、作り出す辞書型キーにも、値添え字にも使い…。
新しい辞書型を作成するのにCopilotから示されたスクリプトでビックリしたのは次の部分でした。
average_result = {wdn: aggregated[wdn] / averages[wdn] for wdn in aggregated}この項の見出しの通り、一回取り出した数値(wdn)を幾度も使い、あっという間に求めるデータセットを作り出しています。ソート未済ですが、鮮やかな使い回しと爺には見えました。
スクリプト:出現数が異なるデータの平均を求める
Pythonが稼働する環境で、「from collections import defaultdict, Counter」が使えるようになっていると動きます。X内の辞書データを適宜増減すると、それに対応した結果を表示します。
# リスト内辞書型データを集計
from collections import defaultdict, Counter
# 'WDN:0~4は曜日番号 mc-mo:数値 曜日番号:0=月~4=金
X = [
{'WDN': 0, 'mc-mo': 29.0}, {'WDN': 4, 'mc-mo': 7.0}, {'WDN': 3, 'mc-mo': -28.0},
{'WDN': 2, 'mc-mo': -9.0}, {'WDN': 1, 'mc-mo': -16.0}, {'WDN': 0, 'mc-mo': -67.0},
{'WDN': 4, 'mc-mo': -47.0}, {'WDN': 3, 'mc-mo': 44.0}, {'WDN': 2, 'mc-mo': -20.0},
{'WDN': 1, 'mc-mo': 28.0}, {'WDN': 4, 'mc-mo': 76.0}, {'WDN': 3, 'mc-mo': 46.0},
{'WDN': 2, 'mc-mo': 58.0}, {'WDN': 1, 'mc-mo': -15.0}, {'WDN': 0, 'mc-mo': -25.0},
{'WDN': 4, 'mc-mo': 9.0}, {'WDN': 3, 'mc-mo': 39.0}, {'WDN': 2, 'mc-mo': 81.0},
{'WDN': 0, 'mc-mo': 0.0}, {'WDN': 4, 'mc-mo': 12.0}, {'WDN': 3, 'mc-mo': -7.0},
{'WDN': 2, 'mc-mo': -2.0}, {'WDN': 1, 'mc-mo': -14.0}, {'WDN': 0, 'mc-mo': -15.0},
{'WDN': 4, 'mc-mo': -28.0}, {'WDN': 3, 'mc-mo': 10.0}
]
# defaultdictを使ってWDNごとの合計を計算
aggregated = defaultdict(float)
for item in X:
aggregated[item['WDN']] += item['mc-mo']
# WDNの値で各種集計
result = [aggregated[i] for i in range(5)] # WDNは0〜4を想定
print(f'曜日番号順:合計値\t{result}\tただし、曜日番号なし=並び順が曜日番号順')
averages = Counter(wdn["WDN"] for wdn in X)
average_result = {wdn: aggregated[wdn] / averages[wdn] for wdn in aggregated}
print(f'曜日番号毎:出現数\t{averages}\tソート未済:0=月~4=金')
sorted_average_result = [round(average_result[wdn], 2) for wdn in range(5)]
print(f'曜日番号順:平均値\t{sorted_average_result}')動かした結果は次のようになりました。
曜日番号順:合計値 [-78.0, -17.0, 108.0, 104.0, 29.0] ただし、曜日番号なし=並び順が曜日番号順
曜日番号毎:出現数 Counter({4: 6, 3: 6, 0: 5, 2: 5, 1: 4}) ソート未済:0=月~4=金
曜日番号順:平均値 [-15.6, -4.25, 21.6, 17.33, 4.83]
Copilot 頼りになるわ~
今回もCopilotにかなり助けてもらいました。耄碌爺の 戯言に根気強く付き合ってくれます。助かります。
なお、VSCodeに滞在中のCopilotの双子の弟は少し反応が異なるようです。Edgeで応答してもらっている双子の兄のCopilotに主に対応してもらってます。
あだ名をつけ、兄:マイク家のこうさん、弟:VSC宅にいる双子の弟、と使い分けてます。
冒頭の「N曜日は損する」云々とはかなり距離のある文末になりました…。すみませぬ。
間違いなどありましたら教えてください、優し目に…。