大容量ファイルから値のないCSVフィールドを削除する

大容量ファイルから値のないCSVフィールドを削除する

だから私はCSVファイルをパラメータとして受け入れ、2つの固有値を持つすべてのフィールドを削除するこのスクリプトを作成しました。とにかく私が扱うデータは各フィールドに2つの値があるからです。これがRedditデータの外観です。

基本的に私がすることは、カットループを使用して各列を繰り返し、各列を一意に並べ替え、2より小さい場合はその列番号を保存することです。次に、書き留めたすべての列番号を繰り返して削除するビッグカットコマンドを生成します。

問題は、大容量ファイルを処理するときに実行が非常に遅いことです。

可能であればスピードアップしたいのですが、高度なコマンドを使用することに慣れていません。誰かが私にこれを達成するためのより速い方法を示すことができれば私は嬉しいです!ありがとうございます。

パスワード:

#!/bin/bash

#find number of fields
num_items=$(cat $1 | head -n 1 | grep -o , | wc -w)
num_items=$((num_items + 0))


echo "Searching all $num_items columns for redundancy"

cols=()

command="-f"
for ((i = 1; i < $num_items; i++))
do
    num_vals=$(cat $1 | cut -d, -f$i | sort -u | wc -w)
    x=$(($num_vals+0))

    #remove column if it has less than 2 values in its column
    #lt 3 as we want to discard the field name at the top
    if [ $x -lt 3 ]
    then
        cols+=("$i")
    fi
    bit="$i-$i,"
    command="${command}${bit}"
done
command="${command}$num_items-$num_items"
echo ""
for col in "${cols[@]}"; do
    sed_reg="s/$col-$col,//"
    command=$(echo "$command" | sed $sed_reg)
    echo "col $col has been removed"
done

command="cut -d, ${command} $1"

$command > pruned_cols.csv

より小さいサンプルデータ:https://ufile.io/27bm31d6

〜70,000行。サンプル:https://ufile.io/qvglxajr

システム:zshを使用するmacOS

ベストアンサー1

これがあなたにどのように役立つかを確認してください。

$ cut --complement -d, -f$(awk -F, '
NR > 1  {for (i=1; i<=NF; i++)  CNT[i, $i]++
        }
END     {for (c in CNT) if (CNT[c] == (NR-1))   {split (c, T, SUBSEP)
                                                 printf "%s%d", DL, T[1]
                                                 DL = ","
                                                }
        }
' /tmp/small_data.csv)  /tmp/small_data.csv

あなたのcutバージョンに対応するオプションがあるとします--complement。それ以外の場合は、印刷ロジックを逆にします。そのセクションで失敗した場合は、awk行ごとの処理を維持してください。NREND

すべての行(タイトルを除く)のすべてのフィールドを調べて、一意のコンテンツを計算します。そのENDセクションの行数CNTからヘッダーを引いたものと同じ場合(つまり、フィールドのすべての行に同じ内容がある場合)、インデックスを分割してフィールド番号を印刷します。

おすすめ記事