一言日記:神エクセルは増えるよどこまでも。
#前置き
不思議なことに世の中には未だに表のようなエクセルを直打ちで作っていることが少なくない。
名前 | 役職 | 年齢 | 名前 | 役職 | 年齢 | |
---|---|---|---|---|---|---|
ネズミ | 神 | 60 | ウサギ | 課長 | 24 | |
ウシ | 部長 | 48 | タツ | 〃 | 12 | |
トラ | 〃 | 36 | ヘビ | 奴隷 | 1 | |
モグラ | 平社員 | 20 | ||||
クマ | 〃 | 20 | 更新日:今日 | |||
表A(〃はセルの結合を表す。トラとモグラの間には空行が一行) | ||||||
更新日とか要らないので下表のようにしてくれればとても助かるのだが、印刷の都合とか、神託とか世の中には色々とある。 |
名前 | 役職 | 年齢 |
---|---|---|
ネズミ | 神 | 60 |
ウシ | 部長 | 48 |
トラ | 部長 | 36 |
モグラ | 平社員 | 20 |
クマ | 平社員 | 20 |
ウサギ | 課長 | 24 |
タツ | 課長 | 12 |
ヘビ | 奴隷 | 1 |
表B |
#主題
表Aを取り込んで、表Bの形にしてからデータとして活用することを考える。
ひとまず力技で組んだのが下記である。
私見では非常にエレファント。ぱおん。
前段
dataframe_raw = pd.read_excel("表A.xlsx")
df_A=dataframe_raw.iloc[:,[*range(0,3)]].dropna(how="all").fillna(method='ffill').astype({'年齢':int})
#ilocでrawdataから0-2列を取出し。[*range()]を使うといちいち0,1,2・・・等と書かなくて良いので便利
#dropna()で、0-3列全てがNaNになっている行を削除
#fillna()を使うと、NaNの真上にあるデータを引っ張ってきてくれるので、結合セルで生じた空白を埋められる
#astypeを使って、float型で読み込まれていた年齢をint型に変更
この時点でdf_Aは下表の感じになる。空行と「〃」は消えているのでヨシ!
名前 | 役職 | 年齢 |
---|---|---|
ネズミ | 神 | 60 |
ウシ | 部長 | 48 |
トラ | 部長 | 36 |
モグラ | 平社員 | 20 |
クマ | 平社員 | 20 |
後段
df_B=dataframe_raw.iloc[:,[*range(4,7)]].dropna(how="all").fillna(method='ffill')
#基本はdf_Aと同じ。ただし、普通にpd_readで読み込むと「同じ列名には.1などの区別用記号がつく」ので注意
df_B.drop(df_B.tail(1).index,inplace=True)
#末尾の更新日情報が不要なので、切り落とす。
df_B.astype({'年齢.1':int})
df_B.columns=("名前","役職","年齢")
#上述の通り、df_Bのcolumnには.1が付いているので名前をつけ直しておく
dataframe_comp=pd.concat([df_A,df_B])
#columnsを同一にしておいたので、concatで縦に結合して完成。
完成品が前置きに書いた表Bである。
#今後の課題
気になるところ
df_B.astype({'年齢.1':int})
df_B.columns=("名前","役職","年齢")
この辺がすごい無駄に感じる。一列に纏めることもできないし・・・。
読み込みの時点でint型を指定したり、columnsの名前を振り直さなくて良い方法がありそうな気配。
あと、**そもそもこの作業自体を一発で処理する方法があるのでは?**と疑っている。
過去にmerge関数を教わった時以来、この手の不安が常に付きまとっているのだ。
参考:https://qiita.com/wellwell3176/items/5e39fd44590603d13291
#参考文献
https://www.366service.com/jp/qa/ee53add5af3296037ee057e49442a821