見出し画像

pandas備忘録(縦結合、横結合)

SASのsetやmergeに該当するファイルの縦結合や横結合をしてみます。

別々のExcelファイルの縦結合

縦結合はconcatを使います。まずは、複数のExcelファイルの縦結合です。

import pandas as pd
dm_Asian=pd.read_excel("dm_Asian.xlsx",sheet_name="Sheet1")
dm_Black=pd.read_excel("dm_Black.xlsx",sheet_name="Sheet1")
dm_conc=pd.concat([dm_Asian,dm_Black])
dm_conc

dm_Asianとdm_Blackのデータが縦に結合したdm_concができます。

for文を使って複数のファイルを一気にまとめましょう。

まずはフォルダ内の特定のExcelファイルのファイル名をlist化します。

from glob import glob
files=glob("dm_*.xlsx")
files

dm_*.xlsxにヒットするファイルが抽出できました。
['dm_Asian.xlsx', 'dm_Black.xlsx', 'dm_Hispanic.xlsx', 'dm_White.xlsx']

これを使ってファイルを縦結合します。

from glob import glob
import pandas as pd

#必要なExcelファイルをlist化
files=glob("dm_*.xlsx")

#空のデータフレームを作る
dm_conc=pd.DataFrame()

#dm_concに足していく
for file in files:
    dm_temp=pd.read_excel(file,sheet_name="Sheet1")
    dm_conc=pd.concat([dm_conc,dm_temp])
    
#subjidでsortしてからExcel変換    
dm_conc.sort_values("subjid").to_excel("dm_結合.xlsx",index=False)
再び縦に結合

pandasはopenpyxlと違い、書式が継承されません。そのためpandasでは後で体裁を調整することになります。

同一Excel内の複数シートの縦結合

これも色々と組み合わせるとできます。まずはシート名の取得です。
openpyxlでもws_list=wb.sheetnamesのような感じで取れますが、ここではpandasでやってみます。

import pandas as pd
file=pd.ExcelFile("Adverse Event.xlsx")
sheet_names=file.sheet_names
sheet_names

openpyxlと同じようなやり方ですね。
['AE', 'AE2', 'Sheet3']というリストができます。このリストから"AE"が頭についた要素だけ取り出します。

import pandas as pd
file=pd.ExcelFile("Adverse Event.xlsx")
sheet_names=file.sheet_names
ae_sheet=[s for s in sheet_names if s.startswith("AE")]
ae_sheet

ここではstartswith関数を内包表記の中で使ってみました。内包表記はまた今度詳しくやります。
['AE', 'AE2']
ここまでできれば、複数のシートを縦結合する方法はファイルごとの縦結合とほぼ同じです。

import pandas as pd
filename="Adverse Event.xlsx"
file=pd.ExcelFile(filename)

sheet_names=file.sheet_names
ae_sheet=[s for s in sheet_names if s.startswith("AE")]

#空のデータフレームを作る
ae_conc=pd.DataFrame()

for i in ae_sheet:
    ae_temp=pd.read_excel(filename,sheet_name=i)
    ae_conc=pd.concat([ae_conc,ae_temp],ignore_index=True)
ae_conc

concatにignore_index=Trueを入れました。こうすることで、indexを振り直してくれます。

横結合

SASと同じでmergeという関数です。どちらかというとsqlに近いですね。

dmというデータフレームとae_concというデータフレームをsubjidをキーとして横に結合します。

dm_ae=pd.merge(dm,ae_conc,on="subjid")

dm_aeデータフレームの変数の並びを変えて、ついでにsubjidで並び替えをします。

dm_ae.iloc[:,[0,6,7,1,2,3,4,5]].sort_values("subjid")
aetermとseverityが左側に来ました

結合とは少し離れますが、変数名のrenameをしてみます。

aeconc2=ae_conc.rename(columns={"subjid":"被験者番号"})
aeconc2
subjidが被験者番号に変わった

では、このae_conc2とdmを横にくっつけてみます。キー変数が異なる場合の結合方法です。

 #変数名違いのmerge 
dm_ae2=pd.merge(dm,ae_conc2,left_on="subjid",right_on="被験者番号")
dm_ae2
キー変数名が変わってもmergeできる

被験者番号の列はもう不要なので削除します。列の削除はこちらで紹介しています。

dm_ae3=dm_ae2.drop("被験者番号", axis=1) dm_ae3

外部結合、左側結合、右側結合

通常の結合では、両方のdataframeでキー変数が一致するレコードだけが出力されます。inner結合です。
外部結合するにはhow=”outer”とします。howは省略するとinnerです。

dm_ae2=pd.merge(dm,ae_conc,on="subjid",how="outer",indicator=True)
dm_ae2

ついでにindicatorオプションもつけました。これをTrueにすると、どっちにあるレコードなのかがわかります。ファイル同士の差分比較をするときに便利ですね。

左側結合はhow="left"です。

dm_ae3=pd.merge(dm,ae_conc,on="subjid",how="left",indicator=True)
dm_ae3

もちろん右側結合はhow="right"

dm_ae4=pd.merge(dm,ae_conc,on="subjid",how="right",indicator=True)
dm_ae4

この記事が気に入ったらサポートをしてみませんか?