課題内容
以下のように、同じディレクトリ配下にサブディレクトリが二つ。
サブディレクトリの中にあるファイル名は同一だが、中身は異なる。
ファイル名が同一のものだけを結合して出力したい。
#備忘録なので、コードの正確性, 解説の精度に関してはご容赦ください。
想定するディレクトリ状況
Main_dir/
├ sub_dirA/
│ ├ file1.csv
│ └ file2.csv
└ sub_dirB/
├ file1.csv
└ file2.csv
求める結果
Main_dir/
├ sub_dirA/
│ ├ file1.csv
│ └ file2.csv
├ sub_dirB/
│ ├ file1.csv
│ └ file2.csv
├ file1.csv (dirAとdirBの結合結果)
└ file2.csv (dirAとdirBの結合結果)
類似した既知の課題
下の様に、同じディレクトリ配下にあるfile1.csv
とfile2.csv
を結合して、新たなfile3.csv
とするコードは既にある。
Main_dir/
├ file1.csv
├ file2.csv
└ file3.csv
->pythonで複数のcsvファイルを1つのcsvファイルにまとめる(ヘッダーが1行だけの前提): 有志のQitta
今回の課題に対するアプローチ
-
input()
を用いて操作するディレクトリを把握させる。 -
os.walk
を用いてディレクトリ状況を把握させる。 - ファイル名が同じ場合に結合するため、1番最初のディレクトリのファイル名のみ取得させる。
- 1, 2で習得した情報を基に
pandas
を用いてファイルを結合する。 - 結合したファイルをcsvとして適当な場所に出力する。
前提条件
・Python 3.9.7
・pandas
結論
import pandas as pd
import os
print("パスを入力")
main_dir = input()
all_dirs=[]
for curDir, dirs, files in os.walk(main_dir):
for now_dir in dirs:
all_dirs.append(now_dir)
all_files=[]
for curDir, dirs, files in os.walk(all_dirs[0]):
for file in files:
all_files.append(os.path.join(file))
counter=0
for now_file in all_files:
df1 = pd.read_csv(all_dirs[counter] +'/'+ now_file)
df2 = pd.read_csv(all_dirs[counter+1] +'/'+ now_file)
df = pd.concat([df1,df2])
df.to_csv(main_dir + '/' + now_file)
解説
事前知識
pandas
の動作に関して
->[Python] 複数のcsvファイルを結合する方法: 外部サイト
os.walk
について
->os.walkを使ってディレクトリ走査: 外部サイト
.append
について
->Pythonでリスト(配列)に要素を追加するappend, extend, insert
import pandas as pd
import os
print("パスを入力")
main_dir = input()
# 走査したいディレクトリを習得する。
all_dirs=[]
# スコープで消えてしまうので、外で定義。
for curDir, dirs, files in os.walk(main_dir):
# 指定したディレクトリを走査する。
for now_dir in dirs:
all_dirs.append(now_dir)
# ここで配下のディレクトリを空のリストにアペンドすることで、ディレクトリが入ったリスト(all_dir)を作成する。
all_files=[]
# スコープで消えてしまうので、外で定義。
for curDir, dirs, files in os.walk(all_dirs[0]):
# ファイル名の入ったリストを作成するが、ファイル名が同じなので一つのディレクトリだけを見れば十分。
for file in files:
all_files.append(os.path.join(file))
# ここで配下のディレクトリを空のリストにアペンドすることで、ファイル名が入ったリスト(all_files)を作成する。
counter=0
for now_file in all_files:
df1 = pd.read_csv(all_dirs[counter] +'/'+ now_file)
# 獲得してきた0番目のディレクトリとファイル名を組み合わせることで、パスを作成し、csvとしてdf1に読み込む。
df2 = pd.read_csv(all_dirs[counter+1] +'/'+ now_file)
# 獲得してきた1番目のディレクトリとファイル名を組み合わせることで、パスを作成し、csvとしてdf2に読み込む。
df = pd.concat([df1,df2])
# df1とdf2をconcatで結合してdfに入れる。
df.to_csv(main_dir+'/'+now_file)
# dfを元のディレクトリをファイル名を組み合わせて、新規ファイルのパスを決めて、出力する。