.csvファイルの一部の行に列がない問題を修正

.csvファイルの一部の行に列がない問題を修正

現在、複数のマージされた.csvファイルのデータを処理しています。残念ながら、これらのマージは時々間違っています。

この例はこれを最もよく説明しています。

「var1」、「var2」、「var3」、「var4」、「var5」
「2001」、「黄色」、「123」、「abc」、「bcdefg」
「2002」、「黄色」、「123」、 「abw」、「asdfkl」
「2001」、「緑」、「abe」
「2002」、「緑」、「abp」
「2001」、「青」、「324」、「abx」、「badsf」
「2002」 ","青色","231","abl","cpq"

したがって、3行と4行ではvar3とvar5の値がありません。変数(列)が欠落しているエラーは常に同じです。

私のCSVは次のように見えたいです。

「var1」、「var2」、「var3」、「var4」、「var5」
「2001」、「黄色」、「123」、「abc」、「bcdefg」
「2002」、「黄色」、「123」、 「abw」、「asdfkl」
「2001」、「緑」、「abe」、
「2002」、「緑」、「abp」、
「2001」、「青」、「324」、「abx」、「badsf」
「2002」、「ブルー」、「231」、「abl」、「cpq」

したがって、行3と4は実際にvar3とvar5の欠損値です。この場合、エラーは「緑」で常に発生するわけではありませんが、他のグループでも発生する可能性があります。

私の考えは、行の列を検索し、列の数がヘッダーの列数(「var1」、「var2」など)と異なる場合は、新しい空の列を追加することです。

複数の異なるファイルに対してこれを行う必要がありますが、実行方法を理解したら、bashスクリプトループを使用できるようになります。

[編集]:明確にしたいです。データセットがかなり大きい。少なくとも19個の変数(列)があります。 (確認する必要がある別のファイルには60を超える変数があります。)

これで、awkを使用するソリューションを検討しています。このような:

awk '{ if (NF<19) {$7=$7","#NA","#NA}}' ファイル 1 > ファイル 2

19列がない場合は、7列の後に2つの列を挿入する必要があります。後で試してみます...

ベストアンサー1

考える最も簡単な方法は、行をカンマで分割し、2つのカンマしかない場所に追加のコンマを挿入することです。明らかな制限は、実際の値にカンマが含まれているとこれが壊れることです。

$ cat test.csv | sed -r 's/^([^,]*),([^,]*),([^,]*)$/\1,\2, ,\3, /g'
"var1", "var2", "var3", "var4", "var5"
"2001", "yellow", "123", "abc", "bcdefg"
"2002", "yellow", "123", "abw", "asdfkl"
"2001", "green", , "abe", 
"2002", "green", , "abp", 
"2001", "blue", "324", "abx", "badsf"
"2002", "blue", "231", "abl", "cpq"

より一般的な内容のためにPythonスクリプトを書くこともできます(CSV機能組み込み)。たとえば、stdinからCSVを読み込み、stdoutに出力するには、次のようにします。

#!/usr/bin/env python
import sys
import csv

missing = [3, 5]  # 1-indexed positions of missing values
missing.sort()  # enforce the increasing order
reader = csv.reader(sys.stdin, delimiter=',', skipinitialspace=True)
writer = csv.writer(sys.stdout)
header = next(reader)  # get first row (header)
writer.writerow(header)  # write it back
for row in reader:
    if len(row) < len(header):
        # row shorter than header -> insert empty strings
        # inserting changes indices so `missing` must be sorted
        for idx in missing:
            row.insert(idx - 1, '')
    writer.writerow(row)

実際のCSVパーサーを使用すると、値やその他の極端な場合にコンマまたは引用符を正しく処理するという利点があります。出力形式も正しいCSVですが、ユーザーの形式とは若干異なります。

$ cat test.csv | python test.py 
var1,var2,var3,var4,var5
2001,yellow,123,abc,bcdefg
2002,yellow,123,abw,asdfkl
2001,green,,abe,
2002,green,,abp,
2001,blue,324,abx,badsf
2002,blue,231,abl,cpq

ご覧のとおり、カンマの後に余分な引用符やスペースはありません。本当に必要な場合は、作成者のためにCSV言語を設定することを考えてみましょう。

おすすめ記事