構造化されてないCSVをpandasで読み込む

投稿者: | 2022-09-30

目次

各行の列数が異なるとエラー

  • ParserError: Error tokenizing data. C error

解消方法1

  • names で列名をむりくり指定して読み込む(事前に最大列数を確認要)
import pandas as pd

colnames = ['col_' + s for s in list('ABCDEFGHI')]
df = pd.read_csv('test.csv', names=colnames)

解消方法2

  • 一度CSVモジュールで読み込み、データフレームに変換するとNoneで埋まり利用可能
import csv
import pandas as pd
import pathlib

with open('test.csv', 'r') as f:
  robj = csv.reader(f) # リスト化する
  df = pd.DataFrmae(robj)

または、skiprowsusecols で読み込む範囲を狭めて(構造化された箇所だけを)読み込むやり方でもよい

過去分・算定からNG行だけを取出し、再作成

import csv
import pandas as pd
import pathlib

# csv_fname = r'/Users/***/Desktop/test_fol/aaa/ng_santei_1.csv'

# tkinterでフォルダを指定させる

base_dir = '/Users/***/Desktop/test_fol/aaa/'

# そのフォルダから、CSVファイルをすべて読み込み、格納

p = pathlib.Path(base_dir)

# csv_new_name = "再投入_" + p.stem + p.suffix
# csv_new_fpath = p.parent / csv_new_name

# ジェネレータのため、取り出す場合はリスト化する、正規表現の方がベター(csv,CSV区別)
csv_f_list = list(p.glob('*.csv'))


# ファイルを一つずつ読み込む(Loop)csv_fname
for csv_fname in csv_f_list:

    print('処理中:' + csv_fname.name)

    # そのままPandasで読み込むと「列数が各行で違いますよエラー」が出るため
    # CSVモジュールで読み込み、_csv.reader(リスト)化後、データフレームに変換する(Noneで埋まる)
    
    # d,df,top,mid,bottom,df_newはリセットしたほうがよい?

    with open(csv_fname, 'r') as f:
        l = csv.reader(f)
        df = pd.DataFrame(l)

        # ファイルが「AAA」分であれば、
        if df.iloc[1,4] == 'AAA株式会社':

            # 処理1(先頭2行を格納)
            top = df[0:2]

            # 処理2(末尾11が「NG」の行を取り出す、NG列がなければ、ループ先頭に戻る)
            mid = df[df[11].str.contains('NG', na=False)]

            # 処理3 「E」行を格納
            bottom = df.tail(1)

            # 処理4 1〜3をがっちゃんこ
            df_new = pd.concat([top, mid, bottom], ignore_index=True)

        else:
            # ループの先頭に戻る
            print('対象外:' + csv_fname.name)
            continue

    # 不要なNoneを削除するため、df_new.valuesでリストへ変換
    # リストからrowを取り出し、Noneを除外したものを戻し、l_2dを作成(=NGのみの算定ファイル)
    # dfのto_csvはすでに使えないはず。
    
    
    l_2d = []

    for row in df_new.values:
        l = [s for s in row if s != None]
        l_2d.append(l)
      
    # ファイル名をリネーム
    csv_new_name = "再投入_" + csv_fname.stem + csv_fname.suffix
    csv_new_fpath = p / csv_new_name
    
    print(csv_new_fpath)

    # NGのみの算定ファイルを書き出す    
    with open(csv_new_fpath, 'w') as f:
        writer = csv.writer(f, quoting=csv.QUOTE_ALL)
        writer.writerows(l_2d)