kakakakakku blog

Weekly Tech Blog: Keep on Learning!

Pandas で NaN を操作する : fillna() と interpolate()

先週紹介した学習コンテンツKaggle Courses : Pandas「欠損値 (Missing data) : NaN」の取り扱いを学んだけど,その後「Pandas ライブラリ活用入門」を読んでいたら「置換 : fillna() 関数」に多くのパラメータがあり,他にも「補間 : interoperete() 関数」という選択肢も載っていた.本書やドキュメントを読みながら,気になった機能を試していく💪

データセット 📈

今回の検証では,本書と同じく GitHub リポジトリ chendaniely/pandas_for_everyone に含まれているデータセット country_timeseries.csv を使う.「エボラ出血熱の発生数と死者数を国別にまとめたデータセット」となり,以下の通り,NaN を多く含んでいる(赤く強調しておいた🖍).なお,今回は結果を単純化するため以下の「5カラム」に限定して載せる.

  • Date : 日付
  • Cases_Guinea : ギニア(発生数)
  • Cases_Liberia : リベリア共和国(発生数)
  • Deaths_Guinea : ギニア(死者数)
  • Deaths_Liberia : リベリア共和国(死者数)
ebola = pd.read_csv('./country_timeseries.csv')
ebola.loc[:, ['Date','Cases_Guinea', 'Cases_Liberia', 'Deaths_Guinea', 'Deaths_Liberia']].head(10)

f:id:kakku22:20210415152636p:plain

1. 置換 : fillna() 関数 📈

pandas.pydata.org

1-1. fillna(0)

まず,fillna() 関数を使うと簡単に NaN を置換できる.例えば,以下のように fillna(0) と実装すると全て 0.0 になる(NaN 以外は黄色く強調しておいた🖍).

ebola.fillna(0).loc[:, ['Date','Cases_Guinea', 'Cases_Liberia', 'Deaths_Guinea', 'Deaths_Liberia']].head(10)

f:id:kakku22:20210415153231p:plain

1-2. fillna(ebola.mean()) / fillna(ebola.median())

とは言え,実践的に使う場合は 0.0 よりも具体的な値で置換することが多いと思う.例えば「平均値 : mean() 関数」「中央値 : median() 関数」と組み合わせると,DataFrame から算出した統計値で置換することもできる.

ebola.fillna(ebola.mean()).loc[:, ['Date','Cases_Guinea', 'Cases_Liberia', 'Deaths_Guinea', 'Deaths_Liberia']].head(10)
ebola.fillna(ebola.median()).loc[:, ['Date','Cases_Guinea', 'Cases_Liberia', 'Deaths_Guinea', 'Deaths_Liberia']].head(10)

f:id:kakku22:20210415153336p:plain

1-3. fillna(method='pad') / fillna(method='backfill')

また fillna() 関数に method パラメータを指定すると「前の値で置換 : method='pad' もしくは method='ffill'したり「後の値で置換 : method='backfill' もしくは method='bfill'できる.「前の値で置換」をする場合,最初から NaN になっている部分は置換の対象外となり,実際に以下の例でも NaN が残っている.

ebola.fillna(method='pad').loc[:, ['Date','Cases_Guinea', 'Cases_Liberia', 'Deaths_Guinea', 'Deaths_Liberia']].head(10)
ebola.fillna(method='backfill').loc[:, ['Date','Cases_Guinea', 'Cases_Liberia', 'Deaths_Guinea', 'Deaths_Liberia']].head(10)

f:id:kakku22:20210415152803p:plain

2. 補間 : interoperete() 関数 📈

Pandas では,特定の値で「置換」するだけではなく,DataFrame から近似した値で「補間」する方法もあり interoperete() 関数を使う.

pandas.pydata.org

2-1. interpolate()

まず,デフォルト設定のまま interoperete() 関数を使うと以下のようになる.カラムの値ごとに「線形的に」補間する.NaN 前後の値で補間をするため,最初から NaN になっている部分は補間の対象外となり,実際に以下の例でも NaN が残っている.

ebola.interpolate().loc[:, ['Date','Cases_Guinea', 'Cases_Liberia', 'Deaths_Guinea', 'Deaths_Liberia']].head(10)

f:id:kakku22:20210415154042p:plain

2-2. interpolate(limit_direction='both')

次に interpolate() 関数で limit_direction パラメータを指定すると,補間する方向として forwardbackwardboth を指定できる.例えば limit_direction='both' のように指定すると,どちらの方向もサポートすることになり,全ての NaN を補間できるようになる.

ebola.interpolate(limit_direction='both').loc[:, ['Date','Cases_Guinea', 'Cases_Liberia', 'Deaths_Guinea', 'Deaths_Liberia']].head(10)

f:id:kakku22:20210415153108p:plain

2-3. interpolate(limit_direction='both')

最後は method パラメータで,デフォルトでは「線形(カラム値を等間隔に補間): linearとなる.選択肢は他にもあり,例えば「インデックス(インデックス値をベースに補間): indexなど.もし index を指定する場合はインデックス値が数値型である必要がある.

ebola.interpolate(method='index').loc[:, ['Date','Cases_Guinea', 'Cases_Liberia', 'Deaths_Guinea', 'Deaths_Liberia']].head(10)

f:id:kakku22:20210415154322p:plain

まとめ 📈

引き続き Pandas を学んでいる.今回は「Pandas ライブラリ活用入門」を読みながら fillna() 関数と interoperete() 関数の気になった機能を試した💪パラメータは他にも多くあるため,ドキュメントも読みながらより理解を深めていく💡

Pandas 関連記事 📈

kakakakakku.hatenablog.com

Jupyter Notebook と Pandas で DataFrame を全て表示するオプション設定

Jupyter NotebookPandas のコードを実装しているときに同じような表示関連設定を繰り返し使うため,メモも兼ねてまとめておく.オプションは他にも多くあり,詳細はドキュメントに載っている.今回は Python 3.9Pandas 1.2.4 を前提とする.

pandas.pydata.org

オプション一覧を取得する 🎯

まず,Pandas では options でオプション一覧(名前空間)を取得できる.例えば display など.また options.display でオプション一覧(display 名前空間)を取得できる.例えば chop_thresholdcolheader_justify など多くある.

dir(pd.options)
# ['compute', 'display', 'io', 'mode', 'plotting']

dir(pd.options.display)
# ['chop_threshold',
#  'colheader_justify',
#  'column_space',
#  'date_dayfirst',
#  'date_yearfirst',
#  'encoding',
#  'expand_frame_repr',
#  'float_format',
#  'html',
#  'large_repr',
#  'latex',
#  'max_categories',
#  'max_columns',
#  'max_colwidth',
#  'max_info_columns',
#  'max_info_rows',
#  'max_rows',
#  'max_seq_items',
#  'memory_usage',
#  'min_rows',
#  'multi_sparse',
#  'notebook_repr_html',
#  'pprint_nest_depth',
#  'precision',
#  'show_dimensions',
#  'unicode',
#  'width']

次に get_option() 関数を使うと,オプション値を取得できる.以下では「表示する最低行数 display.min_rows「表示する最大行数 display.max_rows「表示する最大カラム数 display.max_columnsのオプション値をサンプルとして取得している.なお,今回はデフォルト値として取得している.

pd.get_option('display.min_rows')
# 10
pd.get_option('display.max_rows')
# 60
pd.get_option('display.max_columns')
# 20

また describe_option() 関数を使うと,オプションごとに詳細な説明文やデフォルト値を確認できる.便利!

pd.describe_option('display.max_rows')
# display.max_rows : int
#     If max_rows is exceeded, switch to truncate view. Depending on
#     `large_repr`, objects are either centrally truncated or printed as
#     a summary view. 'None' value means unlimited.
#
#     In case python/IPython is running in a terminal and `large_repr`
#     equals 'truncate' this can be set to 0 and pandas will auto-detect
#     the height of the terminal and print a truncated object which fits
#     the screen height. The IPython notebook, IPython qtconsole, or
#     IDLE do not run in a terminal and hence it is not possible to do
#     correct auto-detection.
#     [default: 60] [currently: 60]

DataFrame を全て表示する 🎯

Pandas で DataFrame を表示すると,以下のようにデフォルトでは省略される.表示する行数に関連するオプションは display.min_rowsdisplay.max_rows で,データセットの行数が display.max_rows を超える場合は display.min_rows を表示するため,今回は「10行」表示されている.なお,今回は GitHub リポジトリ chendaniely/pandas_for_everyone に含まれているデータセット wine.csv を使う.

wine = pd.read_csv('./wine.csv')
wine

そこで set_option() 関数を使って,オプション値を上書きする.display.max_rowsdisplay.max_columnsNone を設定すると「上限なし」となり,DataFrame を省略せずに全て表示できるようになる(以下は 20 行目まで載せている).

pd.set_option('display.max_rows', None)
pd.set_option('display.max_columns', None)
wine

まとめ 🎯

Jupyter NotebookPandas のコードを実装しているときに DataFrame を全て表示するオプションを繰り返し使っていたため,メモも兼ねてまとめておくことにした.引き続き Pandas を試すぞー👌

pandas.pydata.org

おすすめ本

Pandas をもっと学ぶなら「Pandas ライブラリ活用入門」がおすすめ!

書評記事もあわせて読んでもらえればと!

kakakakakku.hatenablog.com

git worktree コマンドを使って複数ブランチを並行して操作する

個人で使っている Git リポジトリ(GitHub リポジトリ)の中に「複数ブランチを並行して操作する頻度が高いリポジトリ」がある.例えば,以下のように「4個」のブランチがあり,どれも操作する可能性がある場合など.今までは頻繁にコミット(git commit コマンド)をしてからブランチを切り替えたり,一時的に退避(git stash コマンド)をしていたけど,頻度が高くなると少し面倒だった.

  • master or main ブランチ
  • branch-a ブランチ
  • branch-b ブランチ
  • branch-c ブランチ

git-worktree(git worktree コマンド)

操作を改善するために調べたところ「git-worktree」という機能があった.今まで知らなかった!そして Git 2.5(2015年7月リリース)から使える機能だった📣「git-worktree(git worktree コマンド)」は,複数ブランチを並行して操作するための機能で,ドキュメントには Manage multiple working trees と書いてある.より正確に表現するなら,指定したブランチを指定したディレクトリ(基本的にどこでも!)にチェックアウトできる.最近使っていて本当に便利なので紹介する💡

git-scm.com

git-worktree : 基本操作(list / add / remove

さっそく基本操作から試していく!今回は検証用の Git リポジトリ sandbox-git-worktree を使う.まず git worktree list コマンドを実行すると「作業ツリー」の一覧を確認できる.最初は master 1個となる.

$ git worktree list
/Users/kakakakakku/ghq/github.com/kakakakakku/sandbox-git-worktree  670f24f [master]

次に git worktree add コマンドを実行して「作業ツリー」を追加する.今回は dummy という名前にする.すると,自動的に dummy ディレクトリが作られる.そして dummy ディレクトリに移動すると master ブランチから dummy ブランチに切り替わっている.

$ git branch --show-current
master

$ git worktree add dummy
Preparing worktree (new branch 'dummy')
HEAD is now at 670f24f Initial commit

$ git worktree list
/Users/kakakakakku/ghq/github.com/kakakakakku/sandbox-git-worktree        670f24f [master]
/Users/kakakakakku/ghq/github.com/kakakakakku/sandbox-git-worktree/dummy  670f24f [dummy]

$ tree ../sandbox-git-worktree
../sandbox-git-worktree
├── README.md
└── dummy
    └── README.md

1 directory, 2 files

$ cd dummy

$ git branch --show-current
dummy

不要になったら git worktree remove コマンドを実行して「作業ツリー」を削除できる.

$ cd ../

$ git worktree remove dummy

$ git worktree list
/Users/kakakakakku/ghq/github.com/kakakakakku/sandbox-git-worktree  670f24f [master]

git-worktree : 既存ブランチを使う

git worktree add コマンドは git worktree add <path> <branch> という構文をサポートしているため,既存ブランチを使うこともできる.例えば branch-abranch-bbranch-c が存在する場合,以下のように「作業ツリー」を追加できる.

$ git worktree add wt-branch-a branch-a
$ git worktree add wt-branch-b branch-b
$ git worktree add wt-branch-c branch-c

$ tree ../sandbox-git-worktree
../sandbox-git-worktree
├── README.md
├── wt-branch-a
│   └── README.md
├── wt-branch-b
│   └── README.md
└── wt-branch-c
    └── README.md

3 directories, 4 files

$ git worktree list
/Users/kakakakakku/ghq/github.com/kakakakakku/sandbox-git-worktree              670f24f [master]
/Users/kakakakakku/ghq/github.com/kakakakakku/sandbox-git-worktree/wt-branch-a  670f24f [branch-a]
/Users/kakakakakku/ghq/github.com/kakakakakku/sandbox-git-worktree/wt-branch-b  670f24f [branch-b]
/Users/kakakakakku/ghq/github.com/kakakakakku/sandbox-git-worktree/wt-branch-c  670f24f [branch-c]

git-worktree : .gitignore と組み合わせる運用案

今の例では <path> として指定したディレクトリ名に wt-branch-a のようにプレフィックス wt- を付けていた.なぜ付けたのかと言うと,master ブランチでは以下のように branch-a などのディレクトリが Untracked files として認識されてしまうからで,誤ってコミットしてしまう懸念があった😇

$ git status
On branch master
Your branch is up to date with 'origin/master'.

Untracked files:
  (use "git add <file>..." to include in what will be committed)
    wt-branch-a/
    wt-branch-b/
    wt-branch-c/

nothing added to commit but untracked files present (use "git add" to track)

そこで .gitignore ファイルに wt-*/ と指定することにより「作業ツリー」を除外している.git worktree add コマンドでは <path> として Git リポジトリ以外のディレクトリを指定することもできるけど,個人的には使いにくく,今回紹介した構成で運用していて便利に使えている.

まとめ

「git-worktree(git worktree コマンド)」を使うと,Git リポジトリで複数ブランチを並行して操作できる.Git 2.5(2015年7月リリース)から使える機能だったけど,今まで知らなかった!運用として複数ブランチを並行して操作する頻度が高いなら便利だと思う!最高👌

Pandas を基礎から学ぶために「Kaggle Courses」の学習コンテンツを受講した

機械学習コンペティションを開催する Kaggle のサイトを見ていたら「Kaggle Courses」という「学習コンテンツ」が公開されていて,Python や SQL や 機械学習など様々なトピックを学べるようになっていた.なんと無料💰現時点でコースは「計17種類」もある.今回は今まで何となく使っていた「Pandas」を学ぶコースを受講してみた.Pandas 未経験者や Pandas の基本的な機能を一通り学びたい人におすすめ👌

www.kaggle.com

アジェンダ 📊

Pandas コースは「計6個」のレッスンから構成されていて,Pandas の基礎(DataFrameSeries)から,Pandas でのデータ取得や欠損値の取り扱いまで幅広く学べる.そして,一歩一歩「歩幅を小さく」学べるため,理解できずに挫折することなく進められる点も素晴らしい!

  1. Creating, Reading and Writing
  2. Indexing, Selecting & Assigning
  3. Summary Functions and Maps
  4. Grouping and Sorting
  5. Data Types and Missing Values
  6. Renaming and Combining

「Kaggle Courses」のレッスンには大きく「2種類」の学習コンテンツがある.まずは「Tutorial」Notebook を読みながら機能を学べる(座学的な).次に「Exercise」Notebook に実際にコードを実装しながら学ぶ(演習的な).特に「Exercise」ではすぐにコードを実装できるわけではなく,ドキュメントを調べたりもするため,理解を深められる仕組みになっていると思う.また以下のような便利機能も組み込まれているため,答え合わせをしたり,ヒントを確認できたりもする.便利!

q1.check()
q1.hint()
q1.solution()

f:id:kakku22:20210410124713p:plain
Exercise 画面サンプル

1. Creating, Reading and Writing 📊

最初は Pandas の代表的なオブジェクトとして DataFrameSeries の操作から学ぶ.それぞれのコンストラクタに Python の dict を指定してオブジェクトを作ったり,index パラメータを指定したりする.コンストラクタ経由でオブジェクトを作れるのはサクッと試すには便利だけど,実用的ではなく,多くの場面ではデータファイルを扱うため,次のトピックに繋がる.

pd.DataFrame({'Yes': [50, 21], 'No': [131, 2]})
pd.DataFrame({'Bob': ['I liked it.', 'It was awful.'], 'Sue': ['Pretty good.', 'Bland.']})
pd.DataFrame({'Bob': ['I liked it.', 'It was awful.'], 'Sue': ['Pretty good.', 'Bland.']}, index=['Product A', 'Product B'])

次に read_csv() 関数を使ってデータファイルを読み込む.read_csv() 関数には多くのパラメータが実装されているけど,今回は index_col パラメータを使って DataFrame の行ラベルを指定している.また読み込んだデータを head() 関数で表示したり,to_csv() 関数でエクスポートしたりする.

reviews = pd.read_csv('../input/wine-reviews/winemag-data_first150k.csv', index_col=0)

animals = pd.DataFrame({'Cows': [12, 20], 'Goats': [22, 19]}, index=['Year 1', 'Year 2'])
animals.to_csv('cows_and_goats.csv')

2. Indexing, Selecting & Assigning 📊

次に Pandas でデータを取得するテクニックを学ぶ.Pandas では Python の構文と同じようにデータを取得することができるため,簡単ではあるけど,Pandas では iloc() 関数(行と列をインデックスで指定する)や loc() 関数(行と列をラベルで指定する)を使う.例えば loc() 関数を条件を組み合わせるとデータに対して AND (&)OR (|) を使うこともできる.他にも isin() 関数を条件に使った例なども学べる.便利!

reviews.iloc[0]
reviews.iloc[:, 0]
reviews.iloc[1:3, 0]

reviews.loc[0, 'country']
reviews.loc[:, ['taster_name', 'taster_twitter_handle', 'points']]

reviews.loc[reviews.country == 'Italy']
reviews.loc[(reviews.country == 'Italy') & (reviews.points >= 90)]
reviews.loc[(reviews.country == 'Italy') | (reviews.points >= 90)]
reviews.loc[reviews.country.isin(['Italy', 'France'])]

3. Summary Functions and Maps 📊

実際に Pandas でデータを扱う場合,単に取得するだけではなく,サマリを取得したり値を変換したりする場面もある.今度はサマリ関数を学ぶ.例えば describe() 関数を使って最小値や最大値やパーセンタイルをまとめて取得したり,min() 関数や max() 関数を使って個別に取得することもできる.他にも平均値や中央値や標準偏差なども取得できる.SQL のイメージと似ている.

reviews.describe()
#               points          price
# count  129971.000000  120975.000000
# mean       88.447138      35.363389
# std         3.039730      41.022218
# min        80.000000       4.000000
# 25%        86.000000      17.000000
# 50%        88.000000      25.000000
# 75%        91.000000      42.000000
# max       100.000000    3300.000000

reviews.price.describe()
# count    120975.000000
# mean         35.363389
# std          41.022218
# min           4.000000
# 25%          17.000000
# 50%          25.000000
# 75%          42.000000
# max        3300.000000
# Name: price, dtype: float64

後半では map() 関数と apply() 関数を使ってデータを変換する.map() 関数は,Series から取得した単一の値を変換する場合などに使って,apply() 関数は,より広範囲に DataFrame 全体の値を変換する場合などに使う.ここまで学ぶと,データをうまく扱えているような気分になってくる!

reviews.points.map(lambda p: p - review_points_mean)
reviews.apply(remean_points, axis='columns')

4. Grouping and Sorting 📊

今度は groupby() 関数を使って値をグループ化して集計する.以下のように「ポイント値」ごとにカウントしたり,「ポイント値」ごとに「値段」の最小値を取得したりできる.また agg() 関数と組み合わせてデータセットのサマリ情報を取得することもできる.

reviews.groupby('points').points.count()
# points
# 80     397
# 81     692
#       ... 
# 99      33
# 100     19
# Name: points, Length: 21, dtype: int64

reviews.groupby('points').price.min()

reviews.groupby(['country']).price.agg([len, min, max])

同じく SQL のイメージと似ていて,データをソートすることもできる.DataFrameSeries に対して sort_values() 関数を使う.

countries_reviewed.sort_values(by='len')
countries_reviewed.sort_values(by='len', ascending=False)

5. Data Types and Missing Values 📊

今度は Pandas で扱う DataFrameSeries「データ型」を学ぶ.Pandas では dtype プロパティで Pandas が解釈をした「型」を取得できる.以下は DataFrame のカラムごとに型を取得している.

reviews.points.dtype
# int64

reviews.country.dtype
# object

また astype() 関数を使うと,型を変換できる.以下は「ポイント値」int64 から float64 に型変換している.

reviews.points
# 0         87
# 1         87
# 2         87
# 3         87
# 4         87
#           ..
# 129966    90
# 129967    90
# 129968    90
# 129969    90
# 129970    90
# Name: points, Length: 129971, dtype: int64

reviews.points.astype('float64')
# 0         87.0
# 1         87.0
# 2         87.0
# 3         87.0
# 4         87.0
#           ... 
# 129966    90.0
# 129967    90.0
# 129968    90.0
# 129969    90.0
# 129970    90.0
# Name: points, Length: 129971, dtype: float64

後半では「欠損値 (Missing data) : NaN」の取り扱いを学ぶ.データセットはキレイに揃ったデータばかりではないため,Pandas では NaN を取り扱う関数が多く用意されている.例えば isnull()notnull()isna()notna()fillna() など.

reviews.region_2.fillna("Unknown")

6. Renaming and Combining 📊

最後はデータセットの名前を変更したり,複数の DataFrame を結合したり,現場で使えそうなテクニックを学ぶ.まず,DataFrame に対して rename() 関数を使ってカラム名やインデックス名を変更する.ただし,インデックス名を変更する場面は少ないとも書いてあった.

reviews.rename(columns={'points': 'score'})
reviews.rename(index={0: 'firstEntry', 1: 'secondEntry'})

そして,複数の DataFrame を結合するために concat() 関数(データセットをシンプルに結合)と join() 関数(rightinner など軸を指定して結合)と merge() 関数(rightinner など軸を指定して結合)を学ぶ.なお,1番複雑な merge() 関数で実行できることはほとんど join() 関数で実行できるため,Pandas コースでは merge() 関数は割愛されていた.それぞれに細かくプロパティがあるため,あくまで基本的な操作を試すところまでを学べる.

canadian_youtube = pd.read_csv("../input/youtube-new/CAvideos.csv")
british_youtube = pd.read_csv("../input/youtube-new/GBvideos.csv")

pd.concat([canadian_youtube, british_youtube])

left = canadian_youtube.set_index(['title', 'trending_date'])
right = british_youtube.set_index(['title', 'trending_date'])

left.join(right, lsuffix='_CAN', rsuffix='_UK')

まとめ 📊

「Kaggle Courses」Pandas コースを受講してみた.わかりやすく歩幅も小さく学べて素晴らしい学習体験だった.さすが Kaggle👏 Pandas の基本的な機能を一通り学べるため,未経験者にもおすすめできる.なお,最後までレッスンを受講すると証明書も取得できるため,モチベーションを刺激する仕組みになっていた!

f:id:kakku22:20210410124743p:plain

最近は Pandas の機能をより深く学ぶため,並行して「Pandas ライブラリ活用入門」を読んでいる.読み終わったら書評記事を書く予定.今回紹介した Pandas コースよりも詳しくまとまっているため,興味があれば読んでみると良いかと📖

Artifact Hub で Helm chart のテンプレートを検索できる新機能「Helm charts templates explorer」

Helm chart を検索するときなどに使う Artifact Hub で,2021年3月頃から新機能「Helm charts templates explorer」を使える.Twitter @cncfartifacthub では 3/5 にアナウンスされていた📣また GitHub Releases を見ると,3/16 にリリースされた v0.17.0 の Change Logs に含まれていた📣しかし Artifact Hub Blog にはまだ紹介記事は出ていなかった!

Helm charts templates explorer を試す

さっそく「Helm charts templates explorer」を試してできることを確認した.今まで Helm chart のマニフェスト(テンプレート)を確認するときは GitHub リポジトリを直接見ていたけど,Artifact Hub でサクッと確認できるのはとても便利💡

  • マニフェスト(テンプレート)一覧を確認できる
  • マニフェスト(テンプレート)をファイル名 or kind(podrole など)で検索できる
  • values.yaml に設定されたデフォルト値を直接確認できる(マウスホバー)
  • Helm chartBuilt-in Objects を確認できる({{ .Release.Name }}{{ .Release.Service }} など)
  • マニフェスト(テンプレート)をクリップボードにコピー / ダウンロードできる

Jenkins Helm chart サンプル

Jenkins Helm chart をサンプルにキャプチャを貼っておく!今後は積極的に「Helm charts templates explorer」を使っていくぞー!

f:id:kakku22:20210401170232p:plain
右側にある TEMPLATES ボタンを押す

f:id:kakku22:20210401170249p:plain
マニフェスト(テンプレート)一覧を確認する

f:id:kakku22:20210401172655p:plain
マニフェスト(テンプレート)を service で検索しデフォルト値を確認する