删除大文件中没有值的 CSV 字段

删除大文件中没有值的 CSV 字段

所以我制作了这个脚本,它接受 CSV 文件作为参数,然后删除其中唯一值少于 2 个的任何字段。这是因为无论如何,我正在处理的数据在每个字段中都有 2 个值。 Reddit 数据看起来就是这样。

基本上我所做的是使用 cut 循环遍历每一列,然后对每一列进行唯一排序,然后如果小于 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

〜70k 行。样本数据: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等于行数减去标题(即该字段在所有行中具有相同的内容),则拆分索引并打印字段号。

相关内容