【发布时间】:2026-01-05 20:35:01
【问题描述】:
sh noob 所以要温柔。这是一个使用命令行的预处理练习,(我在 mac 上)。
我有一个大的 CSV 文件 (original.csv) ~1M 行,4 列。我想创建基于列值提取所有行的处理脚本,即获取所有不同的行。第 1 列中有 138393 个不同的值。我通过 awk 执行上述操作。
从这里我想取这些找到的值的一半,随机排列(或随机选择)然后将两组分成两个 CSV 文件(file1.csv 和 file2.csv)。 FWIW 它用于机器学习练习,因此将数据拆分为测试/训练。
什么是执行此操作的有效方法?我现在拥有的最大瓶颈,(可能更多我没有看到):
- 通过
awk搜索列值匹配 - IO 成本从复制行到单独的 csv,然后遍历每个 csv + 将一半值附加到 train.csv和 test.csv
- 洗牌上面的每个文件
...奖励:任何加速整个过程的多线程解决方案!
我的 CSV 数据是基本数据(并且已经按第 1 列值排序):
1,2,3.5,1112486027
1,29,3.5,1112484676
1,32,3.5,1112484819
1,47,3.5,1112484727
代码:
#!/bin/bash
DATA_FILE=noheader.csv
awk -F "," '{ print >> ("r"$1".csv"); close("r"$1".csv") }' $DATA_FILE # Creates seperate CSV file for each userID
ID_FILE=unique_ids.txt
if [ -e $ID_FILE ]
then
IDX=$(wc -l unique_ids.txt | awk '{print $1}') # Get count of total rows in CSV
printf "Found %d userIDs \n" $IDX
else
printf "File %s Not Found! \n" "$ID_FILE"
printf "Creating Unique IDs File \n"
cut -d , -f1 $DATA_FILE | sort | uniq > unique_ids.txt
fi
COUNT=0
START=$(date +%s)
for ((i=1; i <= $IDX; i++)) # Iterate through each user CSV file
{
FILE=r${i}.csv
TOT_LNO=$(wc -l $FILE | awk -v FILE="$FILE" '{ print $1; close(FILE) }') # Calc total number of rows in file
SPLT_NO=$(($TOT_LNO / 2)) # ~50% split of user row count for test/train split
gshuf -n $TOT_LNO $FILE # Randomly shuffle rows in csv file
head -n $SPLT_NO $FILE >> train_data.csv
OFFSET=$(($SPLT_NO + 1)) # Appends first line# rows of user{n} ratings to training data
tail -n +$OFFSET $FILE >> test_data.csv # Appends rows nums > line# of user{n} ratings to test data
# awk 'FNR==NR{a[$1];next}($1 in a){print}' file2 file1 # Prints out similarities btwn files (make sure not train/test splipapge)
rm $FILE # Deletes temp user rating files before proceding
((COUNT++))
if ! ((COUNT % 10000))
then
printf "processed %d files!\n" $COUNT
fi
}
END=$(date +%s)
TIME=$((END-START))
printf "processing runtime: %d:\n" $TIME
输出(假设它被洗牌):
train.csv
1,2,3.5,1112486027
1,47,3.5,1112484727
test.csv
1,32,3.5,1112484819
1,29,3.5,1112484676
【问题讨论】:
-
请多解释一下有大约一百万行,而不是 "138393 个不同的值在第 1 列"。目前还不清楚这两个输出文件应该是每个 500K 行,还是每个大约 69196 行。