pandasで文字型要素列を辞書型要素列に変換

会社技術

はじめに

ベンダーにDBを作ってもらって社内に入れたとする。一旦入れてしまったものはすぐに変えられず、ちょっと対応に困ることはないだろうか。例えば、他の属性情報もいれたかったが、あまり吟味できないままになっていたとか。。。そして闇に。。。それに対してお手当をしたい。

考えたこと

取り合えず、管理するアイテムに対して、備考を最低限つけていると思う。困ったら備考に書けばよいという発想で1個くらいそのような箱を用意しているのではないだろうか。ここの箱を辞書として扱えば、複数の情報が入れられるのではと考えた。

やってみた結果

とりあえずイメージをつかむ動画を載せる。

この元データは↓だ。

見てもらえば分かると思うが、data5の列を辞書っぽく書いている。これを辞書に変換すると、objectとしてag grid上で表示される。ag gridを使えばobjectの要素に「.」でアクセスできるので、それを編集すればユーザにとっては別データとして扱えるであろう。DB側ではdata5として管理しているが、そんなことはユーザは気にしないはず。。

話の大前提だがDBのインターフェースをstreamlitで構築を想定!!

コード

↓にまとめる。

import streamlit as st
import pandas as pd
from st_aggrid import AgGrid,ColumnsAutoSizeMode
import json

##########設定###########################
df = pd.read_excel("tmp.xlsx")
df=df.dropna()

st.set_page_config(
    page_title="agg cheat", 
    layout="wide", )

#########################################

st.markdown("test")

df["data5k1"]=df["data5"].apply(lambda x: json.loads(x))

gridOP={
    "defaultColDef": {
    "sortable": "true",
    "resizable": "true",
    "filter": "true",
    "editable":True,
    "suppressSizeToFit": True},    
    "columnDefs":[
    {"headerName":"",
    "children":[
        {"field":"index",
         "pinned":"left"}]},
    {"headerName":"Gr1",
    "children":[
        {"field":"data1",
         },{"field":"data2","checkboxSelection":True,},
        {"headerName":"Gr2",
        "children":[{"field":"data3",}]}]},
    {"headerName":"Gr3",
    "children":[
        {"field":"data4",},
        {"field":"data5",},
        {"field":"data5k1",},
        {"field":"data5k1.時間",},
        {"field":"data5k1.場所",},                
        {"field":"data6",}]}]
    }

tmp=AgGrid(df,gridOptions=gridOP,
       layout="wide",
       key="jitan",
       columns_auto_size_mode=ColumnsAutoSizeMode.FIT_CONTENTS,
       allow_unsafe_jscode = True
       )

df
tmp['data']
tmp["selected_rows"]

if t:=tmp["selected_rows"]:
    t[0]["data5k1"]["時間"]

ポイントは↓
df["data5k1"]=df["data5"].apply(lambda x: json.loads(x))
applyで一つ一つの要素をjson形式に変換

あと気に入った書き方を出しておく
if分で同じことを良く書いているなと思い、代入演算子を覚えた。

if t:=tmp["selected_rows"]:
    t[0]["data5k1"]["時間"]

おわりに

DBで箱がないと困ってもあきらめず、ちょっと工夫すればしのげるかも。。
逆にいうなら、とりあえず全部のアイテムに備考を用意すれば文字情報に関してはどうにかなる。余談だが、ファイルは難しい。zipにして入れる手もあるが、、、。個人的には全部のアイテムにリレーションシップアイテムとしてファイルを入れられるようにしておきたいな。#ARAS #後の祭り

コメント