使用AWK

时间:2016-06-19 18:37:39

标签: awk

我的数据框架在结构上与此类似:

    A   C
1   a   1
2   a   2
3   a   3
4   a   4
5   b   5
6   b   6
7   b   7
8   b   8
9   c   9

它有1600万行,我在处理Python时遇到了内存问题。我尝试使用split命令拆分此文件,但我不想将A列中的值分散到不同的文件中。
我不想要这样的事情:

文件一:

 A   C
1   a   1
2   a   2
3   a   3
4   a   4
5   b   5
6   b   6

文件二:

7   b   7
8   b   8
9   c   9

这样的事情会起作用:

文件一:

 A   C
1   a   1
2   a   2
3   a   3
4   a   4
5   b   5
6   b   6
7   b   7
8   b   8

文件二:

9   c   9

如果我不清楚,请告诉我。我写了一个脚本来在python-pandas中完成这项工作,但这需要很长时间。使用awk的任何快速解决方案?

编辑: 我的python脚本要分割这个文件,这个文件花了太长时间。

import pandas as pd
import sys
import os

tp = pd.read_table(sys.argv[1], iterator=True, chunksize=int(sys.argv[2]))
gff3File = pd.concat(tp, ignore_index=True)
i = 0
colNames = ['query_id', 'subject_id', 'percent_idendity', 'align_len', 'mismatch', 'gap_opens', 'q_start', 'q_end', 's_start', 's_end', 'evalue', 'bit_score']
result = pd.DataFrame(columns= colNames)
os.mkdir('splitted')
os.chdir('splitted')
print(len(gff3File))

while True:
    first_gene = gff3File.loc[gff3File["query_id"] == gff3File.query_id.iloc[0]]
    gff3File = gff3File[gff3File["query_id"] != gff3File.query_id.iloc[0]]
    result = result.append(first_gene)
    #print(len(first_gene))
    if len(result) >= int(sys.argv[2]) or len(gff3File) == 0:
        result.to_csv(''.join(['split', "_", str(i), '.csv']), sep = ',')
        print("wrote to:",''.join(['split', "_", str(i), '.csv']))
        result = pd.DataFrame(columns= colNames)
        i+=1
    if len(gff3File) == 0: break

我的数据主管:

query_id    subject_id  percent_idendity    align_len   mismatch    gap_opens   q_start q_end   s_start s_end   evalue  bit_score
LOC_Os01g01010.1    Chr1    100.00  811 0   0   370 1180    7134    7944    0.0 1498
LOC_Os01g01010.1    Chr1    100.00  410 0   0   1592    2001    9208    9617    0.0  758
LOC_Os01g01010.1    Chr1    100.00  202 0   0   1392    1593    8407    8608    2e-101   374
LOC_Os01g01010.1    Chr1    100.00  169 0   0   1   169 3449    3617    4e-83    313
LOC_Os01g01010.1    Chr1    82.25   338 30  19  1669    1996    43230640    43230323    1e-68    265

在这里,我不想在分割时将query_id传播到不同的文件。

2 个答案:

答案 0 :(得分:2)

<强>更新

由于OP想要将几个键分组到一个文件中,我写了一个不太简单的AWK脚本来进行处理!

BEGIN {
    query_count = 0
    file_index = 0
}
{
    if ($2 in arr)
        print >> arr[$2]".split"
    else {
        arr[$2] = file_index
        print > arr[$2]".split"
    }   
    if ( query_count % 5000 == 0 )
        file_index++
    query_count++
}
END {
    for ( key in arr )
        print key ": " arr[key]
}

<强>解释

对于每个 5000 记录,它会将keys分组到一个文件中。对于整个数据库中的任何记录,包含 5000 keys的记录将固定到文件0.split中。之后它会继续增加到1.split,依此类推。

请注意,这并不意味着 5000 记录进入1个文件。一点点仔细考虑应该足以达到数据集的更优化数字, 5000 应该适用于一般的非特定集合。

对于OP的示例,值为5而不是 5000 ,上面的脚本会生成以下输出:

  cat 0.split                                                             
1   a   1
2   a   2
3   a   3
4   a   4
5   b   5
6   b   6
7   b   7
8   b   8
  cat 1.split                                                             
9   c   9

初始天真的解决方案

这个简单的awk脚本可以很好地工作。

awk '{print >> $1".split"}' subset.data

这样做会使用您的query_id.split作为文件名,使用query_id有效地对整个数据进行分组。

在上面的awk脚本上运行时,您的示例会生成以下文件:

  awk '{print >> $2".split"}' temp.data                                   
  cat a.split                                                             
1   a   1
2   a   2
3   a   3
4   a   4
  cat b.split                                                             
5   b   5
6   b   6
7   b   7
8   b   8
  cat c.split                                                             
9   c   9

答案 1 :(得分:0)

IIUC:

您希望将数据框拆分为按列'A'分组的不同文件。

请测试一小部分数据。

df.groupby('A').apply(lambda df: df.to_csv('{}.csv'.format(df.loc[:, 'A'].iloc[0])))
相关问题