LoginSignup
3
1

More than 1 year has passed since last update.

[Python] 別ディレクトリにある同じ名前のcsvファイルを自動結合した。

Last updated at Posted at 2021-09-30

課題内容

以下のように、同じディレクトリ配下にサブディレクトリが二つ。
サブディレクトリの中にあるファイル名は同一だが、中身は異なる。
ファイル名が同一のものだけを結合して出力したい。
#備忘録なので、コードの正確性, 解説の精度に関してはご容赦ください。

想定するディレクトリ状況

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.csvfile2.csvを結合して、新たなfile3.csvとするコードは既にある。

Main_dir/
 ├ file1.csv
 ├ file2.csv
 └ file3.csv

->pythonで複数のcsvファイルを1つのcsvファイルにまとめる(ヘッダーが1行だけの前提): 有志のQitta

今回の課題に対するアプローチ

  1. input()を用いて操作するディレクトリを把握させる。
  2. os.walkを用いてディレクトリ状況を把握させる。
  3. ファイル名が同じ場合に結合するため、1番最初のディレクトリのファイル名のみ取得させる。
  4. 1, 2で習得した情報を基にpandasを用いてファイルを結合する。
  5. 結合したファイルをcsvとして適当な場所に出力する。

前提条件

・Python 3.9.7
・pandas

結論

combi_csv.py
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

combi_csv_with_comment.py
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を元のディレクトリをファイル名を組み合わせて、新規ファイルのパスを決めて、出力する。
3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1