栄養組成計算ツールの作成②
前回は、栄養組成を計算するツールを作成する前段階としてデータベースを作成しました。「TPNelem.xlsx」というファイル名で保存しています。
今回はこの続きからです。
必要な製品のみ選択
データベースから計算に必要な製品のみを選択できるようにします。複数の製品を選択するので、streamlitのst.multiselect()というウィジェットを使用します。以前の投稿で紹介したst.selectbox()と使い方は同じで、製品リストを渡すだけで、リストの中身を選択肢として表示してくれます。selectbox()は1択の場合、multiselect()はその名の通り複数選択の場合に使用します。
データベースの中には製品名も含まれているので、それを利用して製品リストを作成します。
import pandas as pd
df = pd.read_excel('TPNelem.xlsx')
df.head()
Excelデータを読み込むと上記のようなDetaFrameが得られます。使いやすいように「製品名」列をindexに設定します。
df.set_index('製品名', inplace=True)
これで、indexに設定することができたので、df.indexでindexがリストとして取得できます。
df.index
ここで得られるリストをmultiselect()に渡せば複数選択できるウィジェットが完成です。このように、元データを加工してリストを作成すれば、データベースに製品を追加・削除しても自動的に製品リストも更新されるので、メンテナンスが楽になります。
import streamlit as st
products = st.multiselect('薬剤選択', df.index)
multiselect()で選択した項目は、productsという変数にリストとして格納されるので、このリストをもとにDataFrameを加工していきます。
DataFrameの加工
DataFrameを加工して必要な製品だけのDataFrameにしていきます。ここでは、以下の4製品を選択したとしてコードを書いていきます。
products = ['総合|エルネオパNF1号輸液', '電解|塩化Na補正液1mEq/mL', '蛋白|アミパレン輸液', '脂質|イントラリポス輸液20%']
DataFrameから、リストに含まれる製品のみを抽出すればよいのでqueryを使用すれば良さそうです。
df_q = df.query(f'製品名 in {products}')
productsに含まれる4つの製品のみのDataFrameを取得できました。
しかし、よく見るとproductsの順番(multiselectで選択した順番)とdf_qの順番が異なります。
もとのdfから、リストに含まれるものだけを抽出したので、もとのdfの並び順が反映されます。この後、各製品を「○mL使用する」というように液量を入力するため、並び順はproductsの要素順にしておく必要があります。
df_q = df_q.reindex(products)
df.reindex()にproductsを渡すことで、indexを並べ替えることができました。
液量の入力
次に、各製品の液量を入力するウィジェットを作成します。数字を入力するウィジェットはst.number_input()ですが、選択した製品と同じ数だけ表示させる必要があります。製品数はlen()で取得できるので、for文でループすれば良さそうですね。
number_input()で入力される数字を液量リスト(vol_list)に格納して、次の計算に利用できるようにしておきます。
vol_list = [] #空のリストを準備
for i in range(len(products)):
vol = st.number_input(f'{products[i]}(mL)')
vol_list.append(vol)
productsには4つの要素が含まれているので、数字を入力するウィジェットが4つ作られました。number_input()の引数にf-stringsを用いることで、どの製品に対する液量入力ウィジェットなのか分かりやすくなります。
(要素数から考えたのでlen(products)を使用したコードにしていますが、単純に以下のようなコードでも良いですね…。)
for product in products:
vol = st.number_input(f'{product}(mL)')
vol_list.append(vol)
空のリストvol_listに対しappend()することで、productsの順番の液量リストが作成できます。製品とそれに対応する液量がリストになっているので、次からの計算で扱いやすくなります。
次回に続きます。