MS-DOSからの遺産:コマンドプロンプトの世界

本記事は「六間坂上 Advent Calendar 2024」7日目の記事です。
六間坂上 Advent Calendar 2024 - Adventar


お久しぶりです。

なんというか最近技術的なことをしてないと思いつつ
業務上触れることが多いコマンドプロンプト(cmd)でのバッチ処理、プログラミングについて、
linuxのシェルファイルとの違いと共に、触れてみたいと思います。

コマンドプロンプト(cmd)とは

コマンドプロンプトはWindowsの元になったOSである「MS-DOS」を操作するためのシェルです。
シェルとは、OSのカーネルと入力を紐づけるソフトウェア的なものです。
現実世界で言うと、外国人としゃべる際の翻訳機的なものだと思ってください(伝われ)

元々「MS-DOS」を操作するものですが、後方互換という位置づけで残されていて
そのまま今のwindowsにも搭載されているものです。

以下の方法等で起動することができます。
・検索で「コマンドプロンプト」または「cmd」と検索
・windowsキー + rキー を同時押しし、出てきたウィンドウに「cmd」と入力

batファイルについて

linuxであれば、処理をまとめたものを.shファイル(シェルファイル)にまとめて実行することができますが
windowsのコマンドプロンプトでも同じく.batファイルとしてまとめて実行することができます。
例えば、特定のディレクトリに配置されているpythonを実行するのであれば、以下のようなbatファイルになります。

cd file\to\path
python sample.py

batファイルプログラミングについて

cmdがシェルであれば、もちろんプログラミングができます。
逐次処理・条件分岐・繰り返し処理ができるため、これらを駆使すれば色々できます。
一方で、cmd上での処理は高級プログラミング言語で慣れ親しんでいるそれとは
かけ離れていたり、よくわからない部分が多いためこの場で解説してみようと思います。

前提

  • batファイルはwindowsでないと動きません
    • 逆に言えばwindowsであれば大体動きます。
  • コマンドプロンプトで実行する場合、デフォルトではsjisでないと文字化けします
    • windowsだから仕方ないね

batファイルの作り方

テキストファイルを用意して、拡張子を.batに変更すればbatファイルが出来上がります。
ダブルクリックで実行可能です。

基本的なプログラミング手法

逐次処理

逐次処理は実行したいコマンドをそのまま記載すればよいです。
例えばディレクトリを確認したければ、「dir」コマンドで実行できます
基本的に実行したいコマンドをそのまま記載すればよいです。

変数

cmdの変数については、変数の概念が無いため
環境変数を使うこととなります。
環境変数はsetコマンドで使えます。また、参照する際には%%で囲むことで値を参照できます。
シェルと比較すると以下になります。

shell

int_a=10
echo ${int_a}
# echo $int_aでも同じ

cmd

set int_a=10
echo %int_a%

ちなみに、cmdは環境変数をつかっているためか、配列という概念はありません。
ただし、無理やり配列っぽく見せることはできます。
なぜなら、変数名に[]を使うことが許可されているためです。
つまり、以下のような書き方ができます。

set a[1]=10
echo %a[1]%
rem aという配列が作られるわけでは無く、a[1]という名前の変数が作られる
rem ※remはコメントです。

この時点ですでにcmdが癖があることがお判りでしょうか
まだまだ癖のある部分はここからです。

条件分岐

cmdの条件分岐はshellと比べても珍しく癖が少ないです。
ただし、比較演算子がlinuxと少し違っているなど、差別化を図っていたのか何なのかは
分からないですが、統一してほしいですね。

cmd

set numA=1
set numB=1
if %numA% equ %numB%(
  echo "numA と numB は等しい"
) else (
  echo "numA と numB は等しくない"
)

shell

numA=1
numB=1

if [ ${numA} -eq ${numB} ]; then
    echo "numA と numB は等しい"
else
    echo "numA と numB は等しくない"
fi

ちなみに両者とも、ファイルの存在や文字列の比較演算子も用意されているので
気になる方は調べてみてね。

繰り返し

繰り返しはcmdでは上ではとても不思議な構文になります。
見ていただいた方が早いでしょう。
1から10を出力するプログラムをshellの方も合わせて載せておきます。

cmd

for /L %%n in (1, 1, 10) do (
    echo %%n
)

shell

for i in 1 2 3 4 5 6 7 8 9 10
#for i in $(seq 1 5)でも可
do
	echo $i
done

さて、cmd側の構文ですが以下のようになっています。

for %%v in (files) do ( Commands )
 ファイル検索し、対象を対象を検索
 filesの部分を%*にすることでコマンド引数に対してループ処理
for /R %%v in (files) do ( Commands )
 サブフォルダ含めた再帰的ファイル検索
for /D %%v in (directories) do ( Commands )
 ディレクトリを対象に処理を実施
for /L %%v in (start, increment, end) do ( Commands )
 N回ループする
for /F ["FOptions"] %%v in (file) do ( Commands )
 特定のファイルの中身に対して1行ずつループ処理
for /F ["FOptions"] %%v in ('Command') do ( Commands )
 コマンドの実行結果に対して1行ずつループ処理
FOptions ::=
delims=string
tokens=n, ...
skip=n
eol=string
usebackq

さて、書いてあることがわかるでしょうか。
これ実は何に対してループ分を回すかでfor分の構文規則が変わってきます。
説明が難しくなるので以下のように記載します。

for <ループ規則> [<ファイル読み込みオプション>] <ループ変数> in (<ループ対象>) do (<ループ内コマンド>)

さて、cmdのループ文はこれだけでなく、さらに複雑な仕様があるのでそれを紹介します。

オプション引数、ループ変数

例えば、以下のcsvファイルがあります。

# sample.csv
id,str1,str2
1,test,test2
2,hoge,hoge2
3,huga,huga2

上記ファイルをcmdのループ文で処理する際には以下のようなプログラムになります。

for /F "skip=1 delims=, tokens=1,2,3" %%a in (sample.csv) do (
echo %%a
echo %%b
echo %%c
)

おそらく上のプログラムをみて色々考えることはあると思います。

  • skipとtokenってなんだ?
  • なぞのbとcはどこから出てきた?

これについては以下となります。

  • skip:上から何行目までスキップするか
  • token:各行のdelimsで区切られた部分のいくつ目を参照するか
  • 謎の%%bと%%cは何:cmdのfor文ではfor文で宣言された変数を基準として、tokenの数だけ自動でabc順に生成します。%%bで宣言するとtoken=1,2,3の場合%%b,%%c,%%dが自動生成されます。

上記のように意味不明な複雑な仕様があるため、使うときは調べてみてください。

変数スコープ

もちろんループをする際には、ループ外の変数を宣言したり
ループ内で変数に値を格納してループを抜けるという事もしたいはずです。
例えば以下の場合、どのように表示されるでしょうか。

for /L %%n in (1, 1, 3) do (
    set name=Yamada%%n
    echo My name is %name%
)

結果は以下のようになります。

My name is
My name is
My name is

はて、変数はどこに行ったのでしょうか。
実はループの中で、変数を参照してもcmdでは最初にFor文を評価した時点での変数が展開されてしまうため
上手く参照ができません。
そんな場合、遅延展開の命令を付ける必要があります。プログラムで書くと以下です。

setlocal enabledelayedexpansion
for /L %%n in (1, 1, 3) do (
    set name=Yamada%%n
    echo My name is !name!
)
endlocal

その上、変数については%%ではなく!!で囲む必要があります。なぜかは知りません。
シェルスクリプトの場合、そのようなことはする必要なく、普通に参照できます。

関数について

最後に関数について記載しておきます。
コマンドプロンプト、なんと関数という概念がありません。
じゃあどうするかって?GOTOを使います。
この時点で分かる人にはわかる恐ろしさがあると思います。
まあほとんど使うことはないと思うので、今回は特に解説しません。自分でググってください(投げやり)

最後に

今ではpowershellもあるので、コマンドプロンプトを積極的に使おうとする人はあまりいないと思うのですが
業務上で使うことになりそうな人は一度注意点だけでも抑えておいても良いかもしれません。

とはいえ、自分で改めてまとめてみてやっぱ使いたくはないなと思いました。


参考にさせていただいたサイト様

とほほのバッチ入門 - とほほのWWW入門
シェルスクリプトの基本的な書式と考え方 #Linux - Qiita

プライバシーポリシー

プライバシーポリシー
shussy8(以下,「当人」といいます。)は,本ウェブサイト上で提供するサービス(以下,「本サービス」といいます。)における,ユーザーの個人情報の取扱いについて,以下のとおりプライバシーポリシー(以下,「本ポリシー」といいます。)を定めます。

第1条(個人情報)

「個人情報」とは,個人情報保護法にいう「個人情報」を指すものとし,生存する個人に関する情報であって,当該情報に含まれる氏名,生年月日,住所,電話番号,連絡先その他の記述等により特定の個人を識別できる情報及び容貌,指紋,声紋にかかるデータ,及び健康保険証の保険者番号などの当該情報単体から特定の個人を識別できる情報(個人識別情報)を指します。

第2条(個人情報の収集方法)

当人は,ユーザーが利用登録をする際に氏名,生年月日,住所,電話番号,メールアドレス,銀行口座番号,クレジットカード番号,運転免許証番号などの個人情報をお尋ねすることがあります。また,ユーザーと提携先などとの間でなされたユーザーの個人情報を含む取引記録や決済に関する情報を,当人の提携先(情報提供元,広告主,広告配信先などを含みます。以下,「提携先」といいます。)などから収集することがあります。

第3条(個人情報を収集・利用する目的)
当人が個人情報を収集・利用する目的は,以下のとおりです。

  • 当人サービスの提供・運営のため
  • ユーザーからのお問い合わせに回答するため(本人確認を行うことを含む)
  • メンテナンス,重要なお知らせなど必要に応じたご連絡のため
  • 利用規約に違反したユーザーや,不正・不当な目的でサービスを利用しようとするユーザーの特定をし,ご利用をお断りするため
  • ユーザーにご自身の登録情報の閲覧や変更,削除,ご利用状況の閲覧を行っていただくため
  • 有料サービスにおいて,ユーザーに利用料金を請求するため
  • 上記の利用目的に付随する目的

第4条(利用目的の変更)

当人は,利用目的が変更前と関連性を有すると合理的に認められる場合に限り,個人情報の利用目的を変更するものとします。
利用目的の変更を行った場合には,変更後の目的について,当人所定の方法により,ユーザーに通知し,または本ウェブサイト上に公表するものとします。

第5条(個人情報の第三者提供)

当人は,次に掲げる場合を除いて,あらかじめユーザーの同意を得ることなく,第三者に個人情報を提供することはありません。ただし,個人情報保護法その他の法令で認められる場合を除きます。

  • 人の生命,身体または財産の保護のために必要がある場合であって,本人の同意を得ることが困難であるとき
  • 公衆衛生の向上または児童の健全な育成の推進のために特に必要がある場合であって,本人の同意を得ることが困難であるとき
  • 国の機関もしくは地方公共団体またはその委託を受けた者が法令の定める事務を遂行することに対して協力する必要がある場合であって,本人の同意を得ることにより当該事務の遂行に支障を及ぼすおそれがあるとき
  • 予め次の事項を告知あるいは公表し,かつ当社が個人情報保護委員会に届出をしたとき

利用目的に第三者への提供を含むこと

  • 第三者に提供されるデータの項目
  • 第三者への提供の手段または方法
  • 本人の求めに応じて個人情報の第三者への提供を停止すること
  • 本人の求めを受け付ける方法

第6条(個人情報の開示)

当人は,本人から個人情報の開示を求められたときは,本人に対し,遅滞なくこれを開示します。ただし,開示することにより次のいずれかに該当する場合は,その全部または一部を開示しないこともあり,開示しない決定をした場合には,その旨を遅滞なく通知します。なお,個人情報の開示に際しては,1件あたり1,000円の手数料を申し受けます。

  • 本人または第三者の生命,身体,財産その他の権利利益を害するおそれがある場合
  • 当人の業務の適正な実施に著しい支障を及ぼすおそれがある場合
  • その他法令に違反することとなる場合

前項の定めにかかわらず,履歴情報および特性情報などの個人情報以外の情報については,原則として開示いたしません。

第7条(個人情報の訂正および削除)

ユーザーは,当人の保有する自己の個人情報が誤った情報である場合には,当人が定める手続きにより,当人に対して個人情報の訂正,追加または削除(以下,「訂正等」といいます。)を請求することができます。
当人は,ユーザーから前項の請求を受けてその請求に応じる必要があると判断した場合には,遅滞なく,当該個人情報の訂正等を行うものとします。
当人は,前項の規定に基づき訂正等を行った場合,または訂正等を行わない旨の決定をしたときは遅滞なく,これをユーザーに通知します。

第8条(個人情報の利用停止等)

当人は,本人から,個人情報が,利用目的の範囲を超えて取り扱われているという理由,または不正の手段により取得されたものであるという理由により,その利用の停止または消去(以下,「利用停止等」といいます。)を求められた場合には,遅滞なく必要な調査を行います。
前項の調査結果に基づき,その請求に応じる必要があると判断した場合には,遅滞なく,当該個人情報の利用停止等を行います。
当人は,前項の規定に基づき利用停止等を行った場合,または利用停止等を行わない旨の決定をしたときは,遅滞なく,これをユーザーに通知します。
前2項にかかわらず,利用停止等に多額の費用を有する場合その他利用停止等を行うことが困難な場合であって,ユーザーの権利利益を保護するために必要なこれに代わるべき措置をとれる場合は,この代替策を講じるものとします。

第9条(プライバシーポリシーの変更)

本ポリシーの内容は,法令その他本ポリシーに別段の定めのある事項を除いて,ユーザーに通知することなく,変更することができるものとします。
当人が別途定める場合を除いて,変更後のプライバシーポリシーは,本ウェブサイトに掲載したときから効力を生じるものとします。

PandasをRDBと同じように扱うと詰まりやすいところまとめ

この記事は「Unagi-Network Advent Calendar 2023 9日目」の記事です。
Unagi-Network Advent Calendar 2023 - Adventar

前書き

Pandasって皆さんご存じでしょうか。
Pythonでデータ分析をしているそこのあなたであればもちろんご存じでしょう。
おそらくPythonでデータ分析をする際に一番最初に出会うライブラリだと思います。
様々な機械学習フレームワークやデータ分析系のライブラリなどにも利用されているので
そのまま汎用的に使えそうなのも良いポイントです。

このようにもてはやされているPandasですが、実は気を付けないと
ハマりかねないポイントがいくつも用意されています。
今回はそんなポイントを思いつく箇所だけでも記載してみようと思います。

pandasとは

公式には以下のようにPandasが紹介されています。

pandas: powerful Python data analysis toolkit
pandas is a Python package that provides fast, flexible, and expressive data structures designed to make working with "relational" or "labeled" data both easy and intuitive. It aims to be the fundamental high-level building block for doing practical, real world data analysis in Python. Additionally, it has the broader goal of becoming the most powerful and flexible open source data analysis / manipulation tool available in any language. It is already well on its way towards this goal.

pandas · PyPI

日本語に訳すと以下のようになります。

pandas: 強力な Python データ分析ツールキット
pandas は、「リレーショナル」データまたは「ラベル付き」データの操作を簡単かつ直観的に行えるように設計された、高速かつ柔軟で表現力豊かなデータ構造を提供する Python パッケージです。これは、Python で実践的な現実世界のデータ分析を行うための基本的な高レベルの構成要素となることを目指しています。さらに、あらゆる言語で利用できる最も強力で柔軟なオープンソース データ分析/操作ツールになるという幅広い目標もあります。すでにこの目標に向けて順調に進んでいます。

まあPythonで表形式のデータを扱うのを楽にしたライブラリという感じで覚えてもらえればよいです。
DB見たいな処理ができます。

Pandasの最低限の知識

最低限の知識は以下がわかっていれば大丈夫です。
DataFrame:Pandasにおけるテーブルを扱う型のようなもの。ざっくり2次元配列だと理解しておいてください。
Series:Pandasにおけるベクトルを扱う型のようなもの。ざっくり1次元配列だと理解しておいてください。
index:Pandasにおいて、行を一意に指定する添え字。

今回はPandasの初心者向けの使い方については解説はしません。
詳しく知りたい方は以下サイトとか見てみてください。
Pandas 入門 — ディープラーニング入門:Chainer チュートリアル

ただ、Pandas特有の事項で合ったり分かっていないといけない部分に関しては適宜補足をします。

では、Pandasで詰まりやすいところを以下よりまとめてみたいと思います。

Pandasは列指向であること

pandasにてDataFrameを操作したりする時点で少し難しい感覚を覚えると思います。
普段csvから読み込んでいたりするとこの辺意識しないのであれ?となります。

とりあえず表形式なので2次元配列を突っ込んでみましょう。

import pandas as pd

table = [
    [1,2,3,4,5],
    [1,2,1,2,1],
    ['a','b','c','a','b']
]

df = pd.DataFrame(table)
print(df)

上記のプログラムですが実行結果は以下になります。

   0  1  2  3  4
0  1  2  3  4  5
1  1  2  1  2  1
2  a  b  c  a  b

まあそのまま出てきますね。
では、以下の入力はどうなるか想像してみてください。

import pandas as pd

value = {
'a':[1,2,3,4,5],
'b':[1,2,1,2,1],
'c':['a','b','c','a','b']
}
df = pd.DataFrame(value)
print(df)

答えは以下のようになります。

   a  b  c
0  1  1  a
1  2  2  b
2  3  1  c
3  4  2  a
4  5  1  b

あれ?っと思った方も多いのではないでしょうか。
そうなんです、dictを入れるとその列名が指定された状態で入るのです。
普段RDBなどでテーブルを扱う際には行単位で扱うことが多いと思いますが
pandasは列単位で扱う思想が強いです。なので、こういった通常のテーブルを作る際にも
RDBとは違った感覚で実施しないといけません。

ちなみに、2次元配列と同じように入れるためには、以下のように指定をする必要があるみたいです。

import pandas as pd

value = {
'a':[1,2,3,4,5],
'b':[1,2,1,2,1],
'c':['a','b','c','a','b']
}
df = pd.DataFrame.from_dict(value,orient='index')
print(df)

ちょっと面倒ですね。

また、列指向のため特定の行を指定するためには少し工夫が必要です。
通常の2次元配列と同じように扱うと地獄を見ます。

2次元配列では、1行目が欲しければ[1]とかで配列の添え字をつければよいのですが
pandasだと特殊なメソッドを利用しないといけないです。
例えば1行目を取得するには以下です。

import pandas as pd

table = [
    [1,2,3,4,5],
    [1,2,1,2,1],
    ['a','b','c','a','b']
]

df = pd.DataFrame(table)
print(df.loc[0])

少し特殊な関数を使わないといけないです。
(後述しますが、たまたまindexが0なので0と指定していますが、indexが別であった場合はそのキーを指定する必要があります。)

他にも列試行のためデータの挿入や削除に違和感を感じる部分は多いと思います。

上書きがプロパティ依存の話

以下出力の値は何になるでしょうか。
a=5
a+1
print(a)

6と答えたくなりますが、これで出力されるのは5ですね。
なぜなら変数を更新していないからです。

テーブルを扱うpandasでも同じようなことがよく発生します。
dfをいじる関数で出力されるのは自分自身を更新せず、dfのコピーを返します。
例えば行を削除する関数のdropとかはよく引っかかります。

import pandas as pd

value = {
'a':[1,2,3,4,5],
'b':[1,2,1,2,1],
'c':['a','b','c','a','b']
}
df = pd.DataFrame(value)

#上書きされていないのでdfは元のまま
df.drop([1])
print('no inplace:\n',df)

# dfが上書きされる。
df = df.drop([1])
# df.drop([1],inplace=True) こちらでも同じ意味となる。上の方が上書きされたのがわかりやすいので推奨されている。
print('inplaced:\n',df)

del df['a']
# 列の削除は強制上書きされる
print('del:\n',df)

pandasの設計思想とかでしょうか。
書き方には色々あるのですが、代表的な例だと上記のようになります。
(この辺りのシンタックスシュガーがあるのも結構厳しいポイントですね。Pythonは書き方が統一されるのが利点なのに…)

indexが難関な話

RDB上では必須の概念として主キーがあります。
RDBでは特定のカラムを指定して主キーにしますが、pandasでは、主キーと呼ばれるような概念としてIndexが存在します。
Indexはカラムとは別にある存在で、各行を一意に指定するラベルとなります。
ちなみに、インデックス、カラム両方Indexオブジェクトです。
詳細はこの人の記事とか参考になります。
PandasのIndexの理解と使い方まとめ - DeepAge

上記に記載の通り、IndexはあくまでラベルであるのでDBの主キーのような働きはしません。
そもそもDataFrameはRDBのように主キー制約や非NULL制約はありません。
なのでこのようなことは自ら気にしながら実装をしないと盛大にバグります。
例えば以下のようなことが普通にできます。

import pandas as pd

value = {
'a':[1,2,3,4,5],
'b':[1,2,1,2,1],
'a':['a','b','c','a','b']
}
df = pd.DataFrame(value)
print(df)

ちなみに上記実行結果は以下になります。

    a  b
0  a  1
1  b  2
2  c  1
3  a  2
4  b  1

こんな風にRDBとは違って制約は無いので
RDBと同じように使うと意図しない箇所でバグを引き起こす可能性もあります。

RDBとの比較やTipsはこの人の記事が参考になります。
pandas初級者に送りたいTips

無いに型がある話

プログラミング言語において切っても切り離せない存在の型。
型というのはその変数がどのような中身かを表したり、裏側ではメモリの確保に使われたりとプログラミング言語において型というのは意識せざるを得ないものです。

では皆さんに問題です。
数字の6は何型でしょうか。
そうです。代表的なものといえば皆さんご存知int(Integer)型ですね。
実際には数字の6だからといって型が明確にわかるわけではないのですが、大体何の型に入れればよいかは決まっています。

また問題です。
数字の1.6は何型でしょうか。
こちらもfloat型ですね。doubleでも良いですが、少数を表現できる型が必要です。

では、Nullは何型でしょうか。
そうですね。型なんてあるはずがないですね。Nullなんですから。

さて、pandasにはNan(Not a number)という値があります。
ではこいつは何型でしょうか。
察しがいい皆さん流石です。そうですね。float型ですね。

は?と思った皆さん、念のためもう一度言っておきます。
pandasのnanはfloat型です。

では確かめるために実行してみましょう

import pandas as pd

table = [
    [1,2,3,4,5],
    [1,2,1,2,1],
    ['a','b','a','b']
]
df = pd.DataFrame(
    table,
    columns=['col_0','col_1','col_2','col_3','col_4']

)
print(df)
print('type:',type(df['col_4'][2]))

結果は以下となります。

  col_0 col_1 col_2 col_3  col_4
0     1     2     3     4    5.0
1     1     2     1     2    1.0
2     a     b     a     b    NaN
type: <class 'numpy.float64'>

記載の通りNanはNumpyのfloat64型です。
後々話しますが、こいつが結構な悪さをしたりします。

ちなみに、PandasにおけるNullのようなものには
NoneとNanとNaTがあります。
NaTは(Not a Time)の略で、型は「」だそうです。

もう少し詳しく知りたい方は以下とか見てみると良いと思います。
Pythonで値がNaN(Not a Number)、NaT(Not a Time)、None、unknownの違いって? - ts0818のブログ

型推論が邪悪なこと

Pandasは型推論が邪悪な場合があります。

ではここで問題です。
以下のコードで作られるテーブルはどうなるでしょうか。

table = [
    [1,2,3,4,5],
    [1,2,1,2],
]

df = pd.DataFrame(
    table,
    columns=['col_0','col_1','col_2','col_3','col_4']
)

前の実行結果を見ていた方はわかると思いますが、正解はこちらです。

   col_0  col_1  col_2  col_3  col_4
0      1      2      3      4    5.0
1      1      2      1      2    NaN

あれ?型が変わっている奴が一人いますね…
そうなのです。
pandasではデータを読み込むときに型推論が発生し、
最も大きな型に列の値がすべて引っ張られます。

で、先ほど紹介した通り、Nanはfloat型のため
intより型として範囲が大きいfloatとして統一されます…


もっと恐ろしい例を示すと、以下のような場合型がめちゃくちゃになります。

table = [
    ['1',2,3.0,4,5],
    [1,2,1,2],
]

df = pd.DataFrame(
    table,
    columns=['col_0','col_1','col_2','col_3','col_4']
)

print(df.dtypes)

上記を実行した結果が以下となります。

col_0     object
col_1      int64
col_2    float64
col_3      int64
col_4    float64
dtype: object

で、これをそのままCSVなどに出力してしまうと、どうなるかお判りでしょう…
上記の例であれば10個しかデータが無いのでまだ目視確認ができますが
データ分析で1000万行とかの分析をし始めると意図しない事が発生します。
例えばIDで0埋めされている5桁の数値を読み取って
Pandas君が勝手にintだと判断して0を消してしまい条件で一致しなくなるという事も容易に発生します。
対策としてはデータを読み込む際には型を指定したり、pandraというpandasの型チェック用ライブラリを用いたりとかだと思います。

まとめ

PandasはPythonで表形式のデータを扱う上ではとても便利なのですが
RDBっぽく使おうとしたりするとそれなりに困難が発生します。
ただ、この辺きっちりと理解しておけばとても心強い味方になるはずなので
ぜひ色々試してみて詰まってみてください。

背景や課題に興味がある人はさらに以下の記事を読んでみても良いと思います。
(翻訳)Apache Arrowと「pandasの10項目の課題」 #Python - Qiita

AzureMLを使いこなすのが難しかった話

前書き

この記事は「Unagi-Network Advent Calendar 2023 3日目」の記事です。
Unagi-Network Advent Calendar 2023 - Adventar

お久しぶりです!
最終更新が2年前なのですが、今回Advent Carenderにお誘いしていただき、
この2年間ぐらいで溜めておいたものを適当に書いていこうと思います。

前口上

皆さん!機械学習やっていますか!?
最近はクラウドサービスで機械学習ができるものも多くあったりして、ハードルは下がっていると思います。
3大クラウドサービスと言えば、Azure、AWS、GCPですね。各社ともに機械学習のサービスをもちろん持っています。
Googleは機械学習系のサービスが強く、AWSもSageMakerや巨大なサービスを持っていますね。
この2つはインフルエンサーも比較的多い印象です。
さて、ではAzureはどうでしょうか。
AzureはAzure Machine Learning(通称AzureML)というサービスを提供しているのですが、実はあんまり使われていないのでは?
この度色々ありAzureMLを使うことになったのですが、AzureMLを使いこなすのが難しかった話を書いてみようと思います。
※他の機械学習サービスをあまり使ったことが無いためかなり偏見が入っていると思います。

AzureMLとは

一応紹介だけしておきます。
公式紹介では以下のように紹介されています。
「Azure Machine Learningとは企業向け仕様のAI サービスを、
エンドツーエンドの機械学習ライフサイクル全体で利用できます。」
まあよくわかりませんね。
ざっくり説明すると、データの分析、機械学習のモデル作成、デプロイ、運用という機械学習を用いたサービスを作って運用するまでの
一連の流れがすべて1つのプラットフォーム上でできるというものです。
詳しくは以下のURLをご覧ください。
Azure Machine Learning - サービスとしての ML | Microsoft Azure
今回は前書きでも書きましたが、AzureMLを使うことがあったのですが
使うのが難しかった話(罠)を記載してみたいと思います。
※2023年11月時点での話をしております。

破壊的バージョンアップがある件

まず前提として、AzureMLは今リリースされているものとして、v1とv2があります。
バージョンと記載されているので過去の機能は当然使えるものと思っているそこのあなた。
まずその考え方を捨てましょう。

AzureMLはv1とv2では大きく違い、概念そのものが変更されている場合があります。
詳細は以下のサイトとか見てもらうと良いかもしれないです。
Azure Machine Learning SDK v2の基本的な使い方紹介 - ISID テックブログ
MLOps のための Azure Machine Learning CLI v2 / SDK v2 #Azure - Qiita
クラス名や使い方含め大きく変わっているところもあるので自分が今どちらを使っているかを意識する必要があります。

新しい方を使っておけばいいからv2一択では?と思う人も多いでしょう。
実際にMS公式でもv2を推奨しているようです。
Azure Machine Learning CLI と SDK v2 - Azure Machine Learning | Microsoft Learn
もちろん新しい方を使うのはごく普通の考え方だと思います。
しっかりv1からアップデートされているのであればですが…

このv1からv2へのアップデート、機械学習に必要な機能がすべて移行されているわけでは無さそうです。
例えばドリフトと呼ばれる学習するデータに変化が発生しているかを確認する機能はv2には存在しないようです。
(しかもv1もプレビュー版)
そのため、すべての機能を使いこなすためには、v1とv2の情報を両方追う必要があります。
v2で調べて、無ければv1で調べて…という2重に調査する必要があります。

というわけで、自分が今触っているのがv1なのか、v2なのか。そしてその機能は使えるのかをしっかりと調べる必要があります。
(せめてv2のSDKで、v1でできるazuremlの機能は触らせてくれ~)

欲しい情報が探しづらい件

というわけでv1やv2の違いがあるので、情報をしっかりと探す必要があります。
ただ、情報を探すところにも一苦労あります。

例えば、今回触ることになったログ周辺についてですが、
v1ではazureml_runというクラスを用いていたのですが、v2ではmlflowに統合されたようです。
じゃあmlflowのドキュメントを探しに行きましょう。

例えば、ここですね
Python API — MLflow 2.8.1 documentation
MLflowでログが取得したいときにはやはり公式を見るのが一番!
というわけでmlflowの公式を見に来ました。

では混合行列が記録したいので「mlflow.log_table」とかのメソッド使ってみましょう。

実は上記は罠です。azuremlのmlflowにlog_tableというメソッドなどありません。
MLflow を使ったメトリック、パラメーター、ファイルのログ - Azure Machine Learning | Microsoft Learn
azureml公式にも使えるなどとはどこにも書いてありません。
azureml公式をしっかり見ない方が悪いです。

というわけで、外部のOSSをインポートしたとしても
azureml公式に書いてある方が正しかったりします。
(おそらくですが、内部で何か改造されているのかと…嘘だろとは思いますが…)

ちなみにv1時代にはパッケージは違いますがあったそうなので更に混乱を極めます。
SDK v1 から MLflow へのログの移行 - Azure Machine Learning | Microsoft Learn

ドキュメントに書いてない仕様が存在する件

ではしっかりと公式のドキュメントを探してみましょう。
今回はpipelineをデプロイするためのYAMLファイルの書き方を見てみましょう。
※補足説明

  • pipeline:学習や推論など一連の流れを順序指定してまとめて実行するもの、複数のjobからなる
  • job:実行の最小単位。例えばechoコマンドやpythonコマンドのようにコマンドが実行できる。

CLI (v2) パイプライン ジョブの YAML スキーマ - Azure Machine Learning | Microsoft Learn

$schema: https://azuremlschemas.azureedge.net/latest/pipelineJob.schema.json
type: pipeline
display_name: hello_pipeline_abc
settings:
    default_compute: azureml:cpu-cluster
  
inputs:
  hello_string_top_level_input: "hello world"
jobs:
  a:
    command: echo hello ${{inputs.hello_string}}
    environment: azureml:AzureML-sklearn-1.0-ubuntu20.04-py38-cpu@latest
    inputs:
      hello_string: ${{parent.inputs.hello_string_top_level_input}}
  b:
    command: echo "world" >> ${{outputs.world_output}}/world.txt
    environment: azureml:AzureML-sklearn-1.0-ubuntu20.04-py38-cpu@latest
    outputs:
      world_output:
  c:
    command: echo ${{inputs.world_input}}/world.txt
    environment: azureml:AzureML-sklearn-1.0-ubuntu20.04-py38-cpu@latest
    inputs:
      world_input: ${{parent.jobs.b.outputs.world_output}}

pipelineは順番が大事なので上記の例だと
a⇒b⇒cの順番で実行してほしい…のですが
じつはこいつら、各ジョブの入力と出力に依存関係が無いと順番に実行してくれません。
なので上記例だと、aとbは並列に実行し、b⇒cは順番に実行されます。

そんなことどこに書いてあるかって?
「そこに無ければ無いですね」

じゃあ各ジョブで出力が無い場合はどうすれば依存関係が作れるの?
答え:YAMLファイルでpipelineを定義する場合には依存関係は出力以外では作れません。

そんなことどこに書いてあるかって?
「そこに無ければ無いですね」

というわけで細かな仕様に関しては、実行してみるまで分かりません。
実行して、try and errorで進めていく必要がありました。

嘘を書いてある件

とりあえず、ドキュメントに書いてないことは試してみるしかないので試して
では書いてあることはその通りに動くという事で進めましょう。

ではデータドリフト検出機能を使ってみましょう。
※補足説明

  • データドリフト監視:学習データの傾向を見て異常な学習データの変化が発生していないかをモニターする監視。この時のデータの変化をドリフトという。

データセットでデータ ドリフトを検出する (プレビュー) - Azure Machine Learning | Microsoft Learn
(すでにv1しかない and プレビューという記載で嫌な予感しかしないのは置いときましょう。)

とりあえずチュートリアルに従って、独自のデータを用いながら記載してみると…
6か月分のデータを突っ込んでいるのに1カ月分のデータしか出ません。
なぜ…

とりあえず怪しそうな箇所を一通り見ていると、frequencyというパラメータがありました。説明は以下と記載されていました。
パイプラインの実行頻度を示すオプションの頻度。 "Day"、"Week"、または "Month" をサポートしています。
英語で見ても、「Optional frequency indicating how often the pipeline is run. Supports "Day", "Week", or "Month".」
そのままですね。これはただの監視の実行頻度なので関係なさそうです。

…と思ったそこのあなた。まだまだですね。
これ実は半分嘘です。このfrequencyを変えるとデータの表示期間が増えます。
なぜなら、プレビューページに以下の記載があるからです。
「履歴データ分析時の時間範囲は、モニターの頻度設定の 31 間隔までに制限されます。」
なので、実行頻度を変えるとなぜかモニターで表示されるデータの期間も増えます。

このように、ドキュメントに書いてあることでも誤っている場合があるので注意が必要です。
まさしく「公式が勝手に言ってるだけ」状態ですね。

上記踏まえチーム開発で発生したこと

上のようなドキュメントを読みながら、チーム開発をするとどうなるか皆さん想像してみてください。
書いてない、書いてあることが違う、なぜか動かんとかをチーム内で議論するとお祭り状態です。
さらに他の人がなんか一瞬見たことあるけどどこに書いてあったか忘れたみたいなことも容易に発生します。
聞いてもそれが本当かどうかわからないので結局実行したりソースコードを読んだりしてみないとわからない
というオーバーヘッドが半端ではない開発が楽しめます。

まとめ

というわけでそれなりに苦労した難しかった話でした。
あんまり有用な情報が無いので公式を頼るしかないのですがその公式が結構めちゃくちゃでした。
まあ動いたやつが正義という感覚で進めるのも悪くはないのですが
正式にリリースして運用するとなると、どうしてこの記載方法なのかのリファレンスを残したりは
しなければいけないので、自分が実行してそうだったから以外に説明のしようがないのはつらいですね。

ただ、まだプレビュー版だったり、ml環境の発展じたいがすごいスピードで進んでいるので
これから他のクラウドに追いつくレベルで発展してくれればいいなーと思いながらお付き合いしていくことになるのでしょう。。。

最後に一言
「さすがに嘘書くのはやめろ」

海外旅行 in France ~後日談~

旅の終わりの後に色々と語りたい回です。
前回はこちら
shussy8.hatenablog.com


å°Žå…¥

何とか今回も書き終わりました。いや本当に毎回旅行に行くたびにすぐに書いた方が良いのはわかっているのですがどうしても筆が乗らないというかなんというか、行動が遅いんですよね。
今回の旅行は3泊4日(実際は移動時間込みで5日)の旅行となりました。今思い返しても一瞬ですね。
本記事ではこの旅行の感想とか、後日談とか、色々書いてみたいただの自己満足回(今までもそうだったかも…)です。おそらく字ばっかりになると思います。

今回の旅行の感想

というわけで1年越しですが今回の旅行の感想を書いてみたいと思います。

コロナについて

いや本当こいつのおかげですべてが狂わされそうだった。クソクソクソクソ。ホンマクソ。現在進行形でクソ。
確かコロナが騒ぎになりだしたのが2019年の12月ごろだったかな?そこからだんだんと広まってゆき、私たちにも結構な影響を与えました。
この旅行でいえば飛行機が一時期キャンセルになっていけなくなりそうになったということでしょうか。あの時は本当にひやひやしましたね。
最終的に6人で無事にフランスでの旅行を楽しめて本当に良かったです。
現地フランスに到着したときには、アジアの人だからという理由で何か事件とか事故のようなものがあるのではと怖かったのですが、そういったことはなく現地の人は優しく受け入れてくれたように思います。
いや、どちらかというと店員さんは優しいけど、アジア人だからということはなくおそらくそのままの接客だったのでしょうか。治安的にもそのままを体験してきたと思います。
まあ当時のフランスでもマスクを着けている人は全く居なく、私たちもマスクを一日も付けることなく観光を楽しんでいました。
フランスから日本のニュースをたまにチェックしていたのですが、日本の方が当時は流行が激しくて毎日騒いでいましたね。当時は帰れるのかなとかも一瞬考えていました。無事に帰りついた時にはほっとしていました。
そして、私たちが帰ってきた次の週当たりにフランスでの流行が爆発してロックダウンなどが発生していました。
今思い返しても本当にギリギリの旅行だったんだなと思います。もしかすると人生最後の海外旅行なのかもしれないですね。

パリという土地について

パリは行く前はそれこそ何かキラキラしているイメージだったのですが、実際に行ってみると華やかな部分とヤバい部分がはっきりと分かれているような感じだったと個人的に思います。
華やかな部分としては観光名所やレストラン内部などは非常にきれいに整備されていて、とてもその空間に没頭できるように作られていましたね。また、色々な国からの観光客も多いのかそれぞれの国に対する案内もしっかりとあって、日本語での案内も多かったです。
闇の部分としては、本当に治安が悪いところは悪い!私は以前アメリカにも行ったのですけどアメリカよりも治安の悪さを目の当たりにした感じがありましたね。目の前でペンで刺されたり、財布を盗まれそうになっていたりと。アメリカでは自分たちの不注意は結構あったのですが、今回は色々と絡まれることが多いたびになったように思います。
いいところとしては以下のような感じですね。

  • 飯がおいしい

いや本当にご飯がおいしかった!レストランのランダムガチャはさておき、パン屋さんに並んでるものはどれを食べてもおいしかったです!特に忘れられないのは泊まっていたところの近くにあったパン屋で買ったエクレア、今でももう一回食べたいぐらい美味しかったです。あとそのあたりで適当に買ったものも本当に美味しいです。ただのパン屋さんのパンですらおいしいのに、そのあたりのスーパーで買ったワインがまたおいしい。もう何が不味いのかというぐらい美食にあふれていました。アメリカとは違ってごはんがそれぞれ繊細な味の組み立てがされているようで美味しいご飯が食べたいのであればパリはお勧めです。

  • 観光名所だらけ

本当に芸術の街というだけあって、美術館や観光名所が非常に多いです。1週間居ても飽きは来ないんじゃないかなぁと思います。なにせ一つ一つの観光名所が大きいので、そこだけで1日つぶせそうなので、しばらくいてもおそらく飽きないのではと思います。観光名所だけでなく、ただ街をぶらつくだけでも日本の日常では決して見れないような風景や芸術作品が街のいたるところにあるので、のんびりおさんぽもいいと思います。

逆に良くなかったところはこんな感じですかね。

  • 治安

いや本当に治安が悪かった。個人的にはペンで刺されたのと集団で押し寄せてきたのと、スリを目の当たりにしたのと、まあ色々ありますが治安が悪いところは本当に悪いというイメージが非常に強くなりました。
やはり明るい観光客が多く集まってくるところにはこういった輩も集まってくるのかもしれませんが本当に身の危険を感じることが多かったです。
安心できるところは安心なのですが、地下鉄のホームや路地裏、夜の町など危ないところは本当に命が惜しければ行くべきではないところも多くあるので、そういう意味では本当に下調べが重要だなぁと思います。

  • 時間があまりにも短かったこと

これは悪いところというかまあ仕方のないことなんですが、本当に時間が無かった。弾丸ツアーになってしまっていた感じですね。
パリの中ではめぐるところや観光名所がたくさんあり、その一つ一つが1日欲しいぐらい巡れてしまうので、今回の旅も本当に時間が無かったように思えます。
なんかもう少し時間に余裕があれば一つ一つの観光名所をゆっくり巡ったり、のんびりおさんぽする時間が取れたのかもしれませんがまあ仕方ないですね。また次回行くときの楽しみができたという風にも解釈ができると思います。

海外旅行という体験

海外旅行。一度行ってみてもいいと思います。
私は今回のフランスで2回目だったのですが、行くたびに自分の固定概念というか価値観が崩れていくのを実感できます。テレビの中でしか見たことないスリの手口や軍の人が銃を持って普通に街を歩いている姿、地下のたまり場にいるヤバそうなやつやホームレスの乞食など、そういった日本では絶対に味わえないと思えることがそこでは平然と起きています。いや、それがむしろその土地の人たちにとっての日常なんだと思います。こういったヤバい体験や逆に世界的に有名なところに自分の足で赴き、何かを感じるというのも海外旅行でしか味わえない醍醐味です。
なので皆さんも興味があるのであれば、こういう世界に飛び込んでみてもいいのではと思います。あ、くれぐれも自分の命だけは最優先でお願いします。
ちなみになのですが、今回の旅行の予算も大体20万ぐらいだったかな?と思います。これぐらいあれば十分楽しめますよ。

実はタイミング的に色々ヤバかった話

今回の旅行は時間的にいろんな意味でギリギリだったんだなぁと思います。
まずはコロナ。先ほども書きましたが、私たちが帰国した1週間後ぐらいにはフランスはルーブルをはじめとする観光名所が公開停止、そしてそのまま感染爆発を起こしロックダウンするということになっていました。本当にギリギリだったんだぁと思います。下手したらそのまま帰ってこれなかったかも…
また、それとは別に私たちが1日目に行ったエッフェル塔の近くの広場で観光客の殺人事件が起きたりもしています。その写真を見ると私も見たことある光景だったので正直血の気が引きましたね。あと一週間ずれていたら本当にヤバかったんだなぁと思います。本当にラッキーでした。死ななくてよかった。

よかった観光名所best3

ここでは個人的に良かった観光名所best3を決めてみたいと思います。正直決めきれないのですが…

2日目に行った人骨で作った洞窟ですね。なんというか人骨すら芸術にしてしまうのは流石だと思います。涼しいですし、普段のフランスとはまた違った体験ができるのでお勧めです。

1日目の夜に訪れたところです。シャンゼリゼ通りの街路灯や車の光がきらめくのを上から眺めるのは絶景です。行くときは気を付けてくださいね。

個人的には一番良かったと思います。日本では絶対に味わえないあの空間やきらびやかな雰囲気。博物館とか動物園のようなものなら日本でもギリギリ味わえそうなのですが、当時の建物そのままというのはここでしか味わえないのではないでしょうか。もっと隅から隅まで探検してみたいなぁと思います。

よかったお土産

最後に個人的に良かったお土産を書いておきます。もし行く人がいれば参考にでも

  • ワイン

フランスのワインはそのあたりのスーパーで売っている物ですら非常に安くておいしいので、適当に2,3本買って帰ることをお勧めします。今の法律だと900ml以内3本まではokらしいです。実際私もまだ1本寝かしてあります。いつ飲もうか楽しみです。

  • フォアグラ缶

あのフォアグラがたっぷりと詰まった缶詰です。日本だと口にするのも難しそうですが、現地だと安いもので1缶1000円ほどで買えてしまいます。そしてあの味をいつでも食べられるとなるととりあえず1缶ぐらい買っておいていいと思います。

  • 石鹸

これは誰か向けのお土産としてはとても適していると思います。まず紙に包まれている状態ですでにとてもいいにおいがしてくるので、アロマとしても使えそうです。いや本当にいいにおいがします。3個入りとかセットで買って、お土産として渡せば喜ばれること間違いなしです。

  • 衣服など普段身に着けるもの

服は本当に買ってよかったと思います。普段から身に着けるものってやっぱり愛着がわきますし、ちょっと周りの自慢にもなります。服もブランド物でも上質なものが安いですし、買っておいて損はないと思います。個人的には時計もお気に入りです。毎日つけています。

メンバーの感想

ここでは今回一緒に旅行に行ってくれたメンバーの感想も一緒にのせてみたいと思います。

  • KK

「泊まったアパート」
旅行中ずっとお世話になりました。
ご飯食べた後もみんなでダラダラ過ごせるのはホテルにない良さだなと思います。
「サクレクール寺院とヴァンショー」
漫画の影響でずっと興味あったヴァンショーを飲めて満足。
モンマルトルから眺めるパリの街並みも美しく、ずっとここに居たいと思った。
「ジプシー襲来」
↑の直後に発生したゴミイベ。一刻も早く帰国したいと思った。

アパートに関しては本当に良かったですね。適度に広くて騒いでも大丈夫そうですし、何より自由度が本当に高かったです。彼も書いてある通り、ホテルを使わず今回は民宿を使用しました。はじめは治安的な問題とか、サポート的な問題とかで怖かったのですが、今思い返すと民宿でよかったなぁと思います。あのだらだらできる感じが良かった。
サクレクール寺院はKKの提案で観光したのですが、これぞパリという感じがしてよかったですね。広い広場に画家が色々油絵を描いている感じが芸術の街という感じを一層醸し出していました。
この提案が無かったら観光名所を巡って終わっていた可能性もあるので、こういうきれいな街並みを探検できたという経験をさせていただいたKKに感謝です。
ジプシーは…まあね…

  • AH

・集団アンケートおばさんvs主にSK?
・地下鉄のスリ(個人的)
・キャロル
・フォアグラうめぇ

集団アンケートに関してはまたSKさんの時に書きます。
地下鉄のスリは私はただ傍観していたのですが、食らった本人からするとたまったもんじゃないと思いますね。本当に怖かったと思います。見てるこっちも怖かったですもん。前向きにとらえればいい経験になったと…。
キャロルは初日に謎の日本語で書かれた紙を見つけてから、ずっと誰かが「クリスマスキャロルの頃には」という歌を歌ったり民宿で流したり続けていたおかげで、今回の旅のテーマソング的になりましたね。いや本当に謎なんですが誰が何の目的で書いたんでしょうねあれ。
フォアグラは本当に美味しかった!私も一口二口ぐらい分けてもらったのですが、人生で初めて食べるフォアグラのあの濃厚でクリーミーな味!本当に美味しいです。パンにつければ無限に食べれそうなぐらい美味しかったですね。もう一回食べたいなぁ。

  • SK

ボールペンパクられた

これはあれですね。1日目にエッフェル塔の周辺でアンケートと称した何かを仕掛けてくるおばさんたちに色々やられた件ですね。
主に被害者がSKと私で、私は断り続けていたら赤色のペンで指をさされ、SKはあまりにもボールペン頂戴と言われ続けたせいで一本ボールペンをあげたという感じです。
まあ実害はこの2件だけだったのですが、それでも十分ヤバい事件でしたね。エッフェル塔のイメージが奴らのせいであまりよくないものになってしまったのも事実ですし。観光客めがけて突進してくるローブ姿のおばちゃんたちには気を付けようと思いましたね。

  • TT

総括
芸術の都パリの光と闇を体験できた旅だった。
身内に話したら、自分はもとよりメンバーと比べても、身内の対策は粗雑なものだったのに、そんなことされなかったってコメントをもらった。解せぬ。

体調不良者が出なかったこと。
(終盤自分の体調が若干怪しかったことを除けば、)一人も体調を崩さず帰国できたことは、まず喜ぶことかなと。

ゴミイベ多数
正直、反射的に抵抗してしまった時は刺されるかと思った。まあ、後で刺されたのは別の人なんですが。次会った時覚悟してろよ、あのアバズレ。

サングリア
正直舐めてた。めっちゃ美味しかった

全体的に時間が短え
多分、弾丸で行く国ではないなと思った。一つの施設に見所がたくさんあるので、次回はもう少し余裕を持った旅程で行きたい。

全体的に食費が高え
美味しいからいいけど。外貨で金銭感覚が鈍ってることも合わさって、一食にかかるお金がまあまあいく。

飛行機はケチらない
前回のアメリカ旅行の時はチャイナだったけど、今回のエールフランスはマジで快適だったし、何より民度が高かった。慣れない土地に行くので、体力と安全は金で確保するのが吉と再確認。中国のトランジットはもう二度とやりたくねえ。

民泊利用
かなりチャレンジだったけど、雑な飲み会とか、夜まで騒いでも何も言われない環境とか、一定量使ったら水が出るシャワーとかイベントに事欠かないから使ってよかったと思う。

TTが書いてくれたように、まあ良くも悪くも色々面白いイベントが起きる旅行でしたね。いやこのメンバーだと絶対何かしら起きるので飽きはないと思います。
体調不良者が出なかったことは、みんな平和に終わって?忘れているのかもしれませんが、本当に大切なことですね。喜ばしい。みんな胃は丈夫なんでしょうか(一人を除く)。命あっての物種なので、こうして生きて帰ってこれて日常を過ごせることは本当にいいことだと思います。
費用はかければかけるほどまあ旅行のクオリティ的には高くなるわけですが、そこはメンバーややりたいことと相談ですね。個人的には現地の美味しいものや体験ができるのであればそちらにお金をかけて、移動方法に関してはあまり気にしない感じがするのですが、そこは人によってこだわりが出てくるのだと思います。でもいろんな意味で今回は中国の空港は使いたくなかったです。
民泊は今回思い切ってチャレンジしてみて良かったと私も思います。いや本当にわいわいできるのが楽しいので心理的ハードルが許すならばお勧めできますね。

  • SY

観光地的には凱旋門。インパクトあるし夜はライトアップされててよかった
物乞いがやっぱ印象深いなぁSKのペン事件とか、TTの財布に手を突っ込まれたのは普通にやべぇなここって思ったわ

凱旋門は個人的に私もよかったと思います。昼間は下から見て観光し、夜は頂上に上って夜景を眺めました。特に夜のてっぺんから見るフランスの夜景がキラキラときらめていていとても感動的だったのが印象深いですね。
後は物乞いは今回散々苦しめられましたね。おかげで旅の最後の方になるとそういった集団に近づくことすら嫌になりましたからね。

次に行きたいところ

次に行きたいところをなんとなく書いてみます。
フランスはまだまだ楽しめていないところもあるのでもう一度行ってみたいです。
フランス内部でいえば、パリ市内は結構楽しんだのでパリ市外に行ってみたいですね。コルマールという第2のヴェネチアと呼ばれている都市があるそうなのでそちらにも行ってみたいし、あとはモンサンミッシェルも訪れてみたいなぁと思います。パリ市内でも、今回完全には回り切れていない名所やルーブル美術館にはぜひとも再び足を運びたいです。
それ以外の国外となると、個人的にはスペインかイギリスに行ってみたいですね。またどんなたびになるのかはわかりませんが。

最後に

というわけでフランス旅行記でしたが皆さんいかがでしたでしょうか。まだまだ実は書ききれていないところや細かい描写などもあるのですがそれはまたやる気があれば書くのかもしれません。
次にまた海外旅行に行くことがあれば第3弾ができるのですが、果たしてそれはいつになるのやら…
色々旅行とかできにくいこのご時世ですが、まずは今回の騒動が収まるまでみんなで協力して頑張りましょう。
そして、再び今回のような旅行が何のしがらみもなく自由にできる世の中に再びなることをお祈りします。

海外旅行 in France ~4日目~

最後は一気に終わらせましょう!4日目です。
前回はこちら
shussy8.hatenablog.com


朝ごはん

朝起きるととりあえずKKとSYがすでに朝ごはんを食べていたので、残りの私たちも朝からまたパン屋さんに朝ごはんを食べに行くことにしました。
今回の朝ごはんは近くにある2つ目のパン屋さんに訪れてみました。そこでいつものようにクロワッサンとチョコレートのパンを頼みました。
この風景を見ながら散歩するのも最後かなぁと思いながら歩いていたのを覚えています。訪れたパン屋さんはこちら
f:id:shussy8:20210505232507j:plain
そして民宿に帰宅し、ささっと朝ごはんをいただきました。やはりどこのパン屋さんもパンがめちゃくちゃおいしいですね。
f:id:shussy8:20210506195043j:plain
その後、私とTTとSYでルーブル美術館に、それ以外の3人でワインを見に行くとのことで、別れて行動することにしました。

ルーブル美術館

入場まで

さて、別れて行動し始めて、ルーブル美術館に入りました。ルーブル美術館の正面ゲートは昨日も見たのですが、改めてみるとやはり大きくて歴史ある美術館を感じさせます。
f:id:shussy8:20210506195125j:plain
とりあえず美術館のゲートをくぐり、そのまま内部に入ると、かの有名なルーブルピラミッドが見えてきました。近くを通った時には何回か見れていたのですが、改めてみると
とてもきれいな建造物でした。そしてこれがルーブル美術館の入口になっているのはとてもおしゃれですね。
f:id:shussy8:20210506200201j:plain
月曜日の朝早くというのにすごく長い行列ができていて、制限時間が決まっている私たちとしては間に合うのかちょっとびくびくしながら待っていました。

ルーブル内部

それでも30分ほどで中に入れるようになりました。流石の回転率。
というわけでガラスのピラミッドの内部に入ると、そこは広い空間が広がっており、そこをエスカレーターで下っていきました。
中は巨大な空洞が広がっており、はじめはどこに行けばいいのかわかりませんでしたが、とりあえずチケットを買いに行きました。この時点で残り二時間半ほどだったので、音声ガイドも用意されていたのですがそれは使わず、自分の足で色々めぐることにしました。
制限時間も限られているので、ゆっくりと回る時間もなく、有名なところだけをかいつまんでみることにしました。

ここからは写真の中から思い出深いものだけをご紹介します。

モナリザ

やはりルーブル美術館と言えばレオナルドダヴィンチのモナリザでしょう。というわけで一番最初にみんなで見に行きました。
世界で最も見られている絵画ということもあり待ち行列もそれなりの長さでした。
見るとなにか起きるとか、目線がついてくるとか色々なうわさがありますが、実際に見てみると素朴な絵柄で書かれている美しい女性という感じでした。
この絵がどのような魅力があるのか正直言うと芸術の価値があまりわからないのでいまいちわかりませんでしたが、世界で一番有名な絵を見たという実績は解除できたかなと思います。
f:id:shussy8:20210507013744j:plain

サモトラケのニケ

私が結構楽しみにしていた芸術作品です。昔美術の授業で習ったのですが、その形といい、頭が取れているところと言い、美術の教科書で唯一覚えていた芸術作品かもしれません。
実際の配置場所は階段があるホールの中央に飾られていたのですが、その大きさや立派な造形にしばらく見とれていました。
ただ、いったい誰が何のために作った物なのかは覚えていません。
f:id:shussy8:20210507015523j:plain

ナポレオン三世の部屋

ナポレオン3世が住んでいた部屋というか宮殿を再現したり、当時使われていたものをそのまま飾ってあるスペースです。
ここではヴェルサイユ宮殿とはまた違って、さらに豪華絢爛にした内装やティアラなどが飾られており、その1品1品がとてもきれいでした。
時間の都合上、駆け巡ってじっくり見れなかったのですが、再び行くことがあればゆっくり見たいです。
f:id:shussy8:20210507020010j:plainf:id:shussy8:20210507020037j:plainf:id:shussy8:20210507020051j:plain

ハンムラビ法典

「目には目を歯には歯を」で有名なハンムラビ法典です。
実際に見てみると、裏面には字がびっしり書いて合って、有名なところ以外にも名言が含まれているのかなぁと思います。
ただ、ちょっと字が細かすぎてヒビのように見えて少し気持ち悪い感じがあるかも…。
f:id:shussy8:20210507020653j:plain

ルーブルの外へ

時間も少なくなってきたのでお土産を購入しようとおもい売店に行きました。
そこで、ついでなのでお札を使い切りたかったのですが、お札が大きいものしかなく少し困りました。
外国では治安の悪さからレジにお金を置いていることも少なく、大きい額のお札は持ち歩くのさえ嫌だと思われているので、こういったレジの売店でお金を崩すことが難しいのです。
しかし、どうしても使い切りたかったので使ってもいい?と聞くと、おつりが出ないようにしてくれるならいいよと言ってくれたので無事にお札も崩すことができました。ありがとうございます。

そして外へ出ようと思っていたのですが、さすがルーブル。なんというか本当に広すぎて出口がどこにあるのかがさっぱりでした。
先ほどまで美術館の中を駆け回っていたのですが、今度は出口を見つけるために色々なところを駆け巡っていました。
やっとのことで地下から出れそうなところがあり、地上に出たのですが、その途中で謎の黒人のお兄さんに「チケットを出せ」と言われたのでとりあえずその人にチケットを渡しました。
無事に合流できたのですが、一緒にいたSYやTTはそのようなチケットの回収はないと言っていて、おそらくそのチケットで再入場をしてスリを行うんじゃないかという話になりました。
悪気が無いとはいえ犯罪の片棒を担いだことに実質なってしまうのでここでもそのようなことがあるんだなぁと少しショックでした。やはり治安は思っているより悪いようです。

帰宅

一度下宿先へ戻ってきたのですが、別れて行動していた3人はまだ帰ってきていませんでした。それどころか音信不通状態になり心配していました。なぜなら部屋の鍵をその3人が持っていたので
早く帰ってきた私たちは家にも入れずそのあたりをうろうろするしかなかったのです。いや本当に不安でした。
そのあと連絡があり、道路が混んでいてちょっと遅れるという連絡が入った時には本当にほっとしました。そしてその足で帰ってくるまでの間パン屋さんに行って最後におやつを食べることにしました。
燻製されたサーモンが挟まったパンだったのですが、やはり何を買ってもおいしいですね。

そして無事にわかれて行動していた3人も帰ってきて、急いで荷支度を始めました。この時すでにチェックアウトの時間は過ぎていて、さっさと明け渡しをする必要があったからです。
そんな感じで居ると、家の玄関の扉が開錠され突然開き、謎の人が入ってきました。はじめは本当に不審者が入ってきたのかと思いましたが、どうやら部屋掃除をしに来たようで、
さっさと出て行けと言わんばかりの視線をこちらの方に向けていました。いや本当に怖かった。

というわけでさっさと準備をして私たちは家の外へ出ました。この時鍵をその人に渡してきたのですが本当に良かったのだろうか…

露頭からの日本の店へ

さて、そんな感じで今まで過ごしていた家を追い出された私たちですが、とりあえず荷物を預けれる店を探していました。
そして見つけたのが、どうやら日本人向けに荷物の預け入れサービスを行っているところがあるらしく、荷物の置き場を求めてその店に行くことにしました。

荷物を預ける

Uberを使いその店の前にたどり着いたのですが、その周辺はどうやら小さな日本街らしく、結構日本語が書かれていました。久々に見た気がする日本語。
ちょっとびくびくしながらも店のドアを開けると中の店主が日本語で話しかけれくれて少しうれしかったのと安心感があったのを覚えています。
というわけでその人に話をしながら荷物を預けることに成功しました。
今思い返すと、荷物を預けるだけでお金稼げるなんていい商売だなと思います。ありがたいですが。

荷物を預け終わったので、最後の目的地であるラヴァレヴィレッジへ行きました。

ラヴァレヴィレッジ

ラヴァレヴィレッジはフランスの郊外にある巨大なショッピングモールやアウトレット街が集まっているところで、村という名前がついている通り、結構な敷地があります。
フランス最後の場所ということで、ここでのんびりショッピングやお土産を買うことにしていました。
Uberに乗りながら外の風景を眺めていたのですが、パリ市内から出ると、突然近代化したかのようにビルやアパートなどが立ち並んでおり、なんというか不思議な風景だなぁと思っていました。

というわけで1時間ほどかけラヴァレヴィレッジへと到着しました。
f:id:shussy8:20210507025059j:plain

ここでは、特に大きな事件や困ったこともなく、みんなでぶらぶらとショッピングをしていました。
やはり特定の観光地に行くのも面白いですが、こういった現地ならではのものをのんびりショッピングするのもいいなと思います。
ここでは家族や友達へのお土産、自分の服や欲しかった時計など色々買いました。いやー散財した気がします。
個人的にはCelioというメーカーがおしゃれな服を置いており、しかも安かったのでお気に入りです。
あと人生で初めてたばこを買いました。まあ私は吸いませんが。

最後の晩餐(日本食)

そんな感じでみんなでショッピングを終え、荷物を預けた場所に戻ってきました。この時点で夜も更けてきて、近くでご飯を食べようということになっていましたが、
近くのフランス料理屋が見つからずそのあたりにあった日本料理店に入ることにしました。
前回に引き続き今回も外国で日本料理をたべるのかこいつら。まあこれも旅の醍醐味でしょうか。

フランス最後のご飯がこちら。味噌ラーメンです。日本の味ですね。少し薄かったようにも思えますが。
f:id:shussy8:20210507030812j:plain

今回訪れたお店はこちら。
goo.gl

さらばフランス

ご飯を食べ終わって、荷物を受け取るとすでに空港へと向かわなければいけない時間でした。
なのでUberを呼んで空港へ行くことにしました。Uberが来るまでの間、この光景も最後かぁと思いながらフランスの街並みに輝く光を見ながら、旅の思い出にふけっていました。
最後にお土産屋さんとかないかなーとかうろうろしていましたが無かったので諦めました。

そしてやってきたUberに乗り、パリの街を後にするのでした。

さて、シャルルドゴール空港に行く途中で飛行機の確認をしていたのですが、どうやらシャルルドゴール空港はめちゃくちゃ広いらしく、搭乗口を間違えるととんでもないことになるので落ち着いて探していました。皆さんも空港に行くときにはお気をつけてください。
空港に着いたらまずはいつものように荷物の整理をしたり、パンを食べたりして、荷物を預けに行きました。
ここで最後にやらかすのが私たち…というか私なのですが。

空港に荷物を預けていたのですが、どうやらそのうちの一つが軽すぎるらしく荷物でエラーが出ました。なので空港の職員さんになんかあっちの方へ持って行ってくれと言われました。多分…
なので全力で走っていったのですが全くどこに預ければいいのかわからず、持って行ってくれと言った職員さんに申し訳なさそうにわからないと言いました。すると、その軽い荷物を預ける場所に一緒に連れて行ってくれました。談笑していたのにもかかわらずわざわざ対応してくれてありがとうございます。イケメンのお兄さんでした。

遅れてみんなと合流して身体検査を行い、搭乗口の方に向かうことにしました。搭乗口に行く時に電車を使ったのですが、まず空港内に電車があるのに驚いたとともに、電車を使わないと違う搭乗口にすらいけないというのがここの広さを物語っているなぁと思います。本当に空港の場所を間違えると大変なことになるのでお気を付けください。
最後に売店で色々見つつ飛行機を待つことにしました。ここでまたいつものように悪乗りで意味不明な飲み物を買いましたが、なんというか微妙な味だったのを覚えています。
f:id:shussy8:20210507034233j:plain

そして皆で飛行機に乗り、そのまま眠りに落ちるのでした。さらばフランスまた来る日まで…
さて、最後にお楽しみの機内食がありますね。

まずは1食目。このような感じでした。パンもそれなりに美味しかったのですが、やはり現地で食べるものとはまた違った感じがしました。ただデザートはおいしい。
f:id:shussy8:20210507034620j:plain

そして2食目。朝ごはんにはぴったりのパンとフルーツのセットでした。あっさりしていてとても美味しかったです。
f:id:shussy8:20210507034624j:plain

日本到着

さて、機内食を食べて寝てを繰り返しているとあっという間に日本に到着していました。
f:id:shussy8:20210507035229j:plain
これは空路を示したモニターなのですがこんなに長い距離を旅していたのかと思うと感慨深いですね。

というわけで無事に降り立って、ロビーの方へ行くと一番最初に思うのはやはり「日本語が書いてある!」ですね。
前回のように長期間ではなかったので衝撃は少なかったのですが、それでも日本に帰ってきたんだなぁと実感できました。
それとともに色々なニュースも入ってきました。国内ではコロナがそれなりに流行してきてた時期だったので大変なことになっているとの感じでした。
それに周りの人もマスクをしていて、フランスより深刻な状況なのではと思っていました。


さて、無事に荷物も受け取りみんなで旅の終わりを少し悲しみながら一部は解散しました。
残ったメンバーでご飯を食べに行ったのですが、やはり日本に戻ってきたら日本っぽいものが食べたい!ということで和食屋さんに入り、和食セットを注文しました。
f:id:shussy8:20210507035827j:plain
そばやネギトロ丼を食べると、フランス料理もそれはおいしかったが、やっぱり日本料理が口に合うなぁと思いました。
そしてそのまま解散し、次の日の仕事に備え、家に帰宅しベッドに入るのでした。

次回

さて無事に日本へとたどり着いた6人。
この旅行の感想やら何やら、後日談やらを振り返りたいとおもいます。
次回「ビール片手に思い出語り」お楽しみに

海外旅行 in France ~3日目 後半~

旅もいよいよ佳境!3日目後半です。
前回はこちら
shussy8.hatenablog.com

昼めし後

一度美術館の前の大通りに出た後、そのあたりをうろうろしながらUberを待っていました。
f:id:shussy8:20210505173601j:plain
私たちはUberで離れたところにあるパン屋さんに行くことにしました。パン屋さんがある場所はマレ地区と呼ばれていて、日本でいうと新宿2丁目的なところです。
そのパン屋さんはパリでも人気上位に位置するパン屋さんで、そのパンを食べに行くことにしました。
しかしUberで着いたところは私たちが行きたいところとは違っていて、しかもその店は違っていました。悲しみ。
ちなみに訪れたパン屋さんはこんな感じでした。
f:id:shussy8:20210505192536j:plain

このような形で時間をつぶし、私たちは次の目的地である教会へと足を運びました。

サントゥスタッシュ教会

というわけで私たちは次の目的地であるサントゥスタッシュ協会へとやってきました。
この教会はパリでも最大級のもので、そこには世界でも類を見ないほどのパイプオルガンがあるとのことでした。しかも毎週日曜日にはここでこのパイプオルガンの無料演奏会を開くとのこと。
なので私たちもここでパイプオルガンの演奏を聴くことにしていました。

教会内部

教会の外では結構な人がいて、迷子になりそうでしたが無事に入ることができました。
中ではきれいなステンドグラスやものすごい高い位置にあるパイプオルガンのパイプを見ながら圧巻を受けてました。
f:id:shussy8:20210505211553j:plainf:id:shussy8:20210505211617j:plain
中に入ってしばらく待っていると、中央の台座に人が数人達はじめ、何やら言っていました。おそらく聖書か何かの内容を語っていたのだと思いますが、何もわかりませんでした。
そうしていると、いよいよパイプオルガンの演奏が始まりました。

パイプオルガンの演奏

パイプオルガンの演奏は最初は一音一音丁寧に演奏されていました。その音が静かな教会内部に響き渡り、きれいな音を奏でていました。
流石これだけ巨大だと迫力もあります。しかしその音は心を落ち着かせるような心休まる音でした。

このような感じで演奏が進んでいましたが、その安らかで壮大な音を聞きながら、だんだんと眠気が襲ってきました。
そして近くに空いていた椅子に座ると、そのまま寝てしまいました。
気付いた時には演奏もほぼ終わっており、最後の拍手の途中でした。
というわけで私は教会で聖なる音楽を聴きながらすやすや居眠りをしていたそうです。一緒に居た友達曰く、最後はとても力強い迫力ある演奏だったそうで、聞きたかったなぁ。まあこれもいい思い出かも。

教会外部

演奏が終わるとみんな一斉に教会の外側へ出始めたので、私も一緒に流れに乗って出ようとしました。
しかし周りには友達はおらず、みんなどこにいるのかわからないまま、流れに乗って外へ出ました。入口と出口が前と後ろにあって適当に前の方から出ましたが、みんなは後ろの方から出たらしくそのまま私が教会を半周して合流しました。スマホが無い時代はみんなどうやって合流していたんだろうと本当に思います。

教会の外側には、謎の頭だけのオブジェが置いてあり、そこでみんなで写真を撮りました。古くからある教会にも関わらず現代アートにも前向きなのはいいことだと思います。
f:id:shussy8:20210505214333j:plain
なんでもこのオブジェも結構有名なものらしいので興味のある人は調べてみてください。

フォーラム・デ・アール

サントゥスタッシュ教会のオブジェの向こう側にとても巨大な建造物があったのでそこに行ってみることにしました。
その建造物は木造で周りの中世代な雰囲気の建物と比較してもとても近代的な形の建造物でした。
f:id:shussy8:20210505215358j:plain
そこはフォーラム・デ・アールという名前の巨大なショッピングモールだったので、お土産を見つつそこでお買い物をすることにしました。
どれぐらい巨大化というと、そのショッピングモールで1日つぶせそうなぐらい大きかったです。なんせ地上だけでなく地下4階まであるのですから。

その中で私たちはそれぞれ洋服やお土産など思い思いのものを購入しました。

一度帰宅

そのあと一度民宿先に帰りました。そこで荷物を整理して、再び私たちは凱旋門近くに降り立つことにしました。

バストロノーム

凱旋門近くに降り立つと、そこには私たちが乗るバスが待機していました。
f:id:shussy8:20210505221018j:plain
このバスはバストロノームというツアーに使用されるバスです。バストロノームとは、パリの有名な観光名所をバス内部で食事を楽しみながら観光できるバスツアーです。
個人的に何が良いかというと、ただでさえ危険な夜のパリを何の害もなくバス上から楽しめるということです。観光名所を一度で楽しみたいのであれば私的にはお勧めのツアーです。

搭乗

バスに登場するとそこにはすでにメニュー表とワイングラスが並べられていました。そしてみんなが席について談笑しているとバスの乗務員の人がシャンパンを持ってきてくれました。
凱旋門を背にしながらシャンパンを飲めるのはこのツアーならではだと思います。
f:id:shussy8:20210505222059j:plain
ツアーの道はこのような形で進んでいくとのことでした。
f:id:shussy8:20210505222332j:plain
各名所にはそれぞれ音声でのガイドがついており、どのようなところかを教えてくれます。それを聞きつつ談笑しながらバスツアーがスタートしました。

バスツアー

バスツアーでは最初に凱旋門からスタートし、オペラ座、ルーブル美術館、ノートルダム大聖堂、エッフェル塔とパリの各所をめぐりながら、パリのコースメニューを堪能していました。
また、この3日間で訪れた場所やその思いで、今度はこういうことをしたいねという話をしながら、ツアーを楽しみました。
コースでは、このようなメニューが提供されていました。カニや魚、肉など幅広いコースでどのメニューもとても美味しかったです。
f:id:shussy8:20210505224131j:plainf:id:shussy8:20210505224144j:plainf:id:shussy8:20210505224157j:plainf:id:shussy8:20210505224211j:plainf:id:shussy8:20210505224225j:plainf:id:shussy8:20210505224117j:plain

また、エッフェル塔についた時にはこのバスツアーの時刻と合わせていたのか、ちょうどイルミネーションが光るタイミングだったのでその前で記念撮影をしました。
普段昼に見るエッフェル塔と比べてもその輝きがとてもきれいでした。
f:id:shussy8:20210505224435j:plain

そして長いようで一瞬だったバスツアーを終えると、私たちはその足で家に帰りました。
いよいよ明日で最終日だねぇとかそんなことを話しながら、パリでの最後の夜を残ったワインとおつまみを食べながら過ごし、
そのまま眠りにつくのでした。

次回

いよいよ旅も佳境!
旅の佳境にふさわしく迷宮に迷い込む。さて、迷い込んだ迷宮から無事にみんな脱出できるのか!?
次回「地下迷宮とショッピング」お楽しみに。