使用命令行工具向大型数据集添加属性

时间:2013-10-02 06:08:28

标签: attributes command multiple-columns

我有一个非常大的数据集(大约150 MB; 500个目标; 700,000多个属性)。我需要在每个文件的末尾添加一个属性。 我正在使用的日期文件具有以下结构:

@relation 'filename'
@attribute "place" string
@attribute "institution" string
@attribute "food" string
@attribute "book" string

@data
3.8,6,0,0,church
86.3,0,63.1,0,man
0,0,0,37,woman

我需要在@data之后的每一行中添加一个信息属性。 但是,由于其属性数量庞大,我无法在文本编辑器中打开和修改数据。 我需要包含的属性我在一个单独的制表符分隔文件中,该文件具有以下结构:

church  1
man 1
woman   0

所需的结果将使数据集如下所示:

@relation 'filename'
@attribute "place" string
@attribute "institution" string
@attribute "food" string
@attribute "book" string

@data
3.8,6,0,0,church,1
86.3,0,63.1,0,man,1
0,0,0,37,woman,0

如果命令看起来与@data后的每一行的末尾匹配第二个文件的每一行,如果匹配则添加相应的0或1。

我一直在寻找解决方案,我的搜索主要是提出了指向使用文本编辑器的方向的答案。正如我前面提到的,文本编辑器的问题不一定是打开文件(例如UltraEdit可以处理大部分这种大小的文件)。它是在超过700,000个属性之后手动插入一个属性,这是一项非常耗时的任务。

所以,我问社区我是否需要使用命令行参数(awk / grep等)来实现所需的结果?

2 个答案:

答案 0 :(得分:1)

Python很棒,因为它默认安装在很多基于POSIX的系统上:)

现在有些警告:

  • 这是一个简单的python,旨在让你随时学习,因此它可以更加优化
  • 这会在处理过程中将整个文件读入内存,所以如果你的文件在GB中,它会打到你的计算机上
  • 如果你想知道发生了什么,我建议抛出一些print语句,或使用python调试器逐步完成程序。

以下是我提出的建议:

lookup = {}
output_list = []

# build a lookup based on the lookup file
with open('lookup.csv', 'rb') as lookup_file:
    rows = lookup_file.readlines()

    for row in rows:
        key, value = row.split()
        lookup[key] = value

# loop through the big file and add the values
with open('input-big-data.txt', 'rb') as input_file:

    rows = input_file.readlines()
    target_zone = False

    for row in rows:

        # keep a copy of every row
        output_for_this_row = row

        # skip the normal attribute rows
        if row.startswith('@'):
            target_zone = False

        # check to see if we are in the 'target zone'
        if row.startswith('@data'):
            target_zone = True

        # start parsing the rows, but not if they have the attribute flag
        if target_zone and not row.startswith('@'):
            # do your data processing here
            # strip to clobber the newline, then break it into pieces
            row_list = row.strip().split(',')
            # grab the last item
            lookup_key = row_list[-1].strip()
            # grab the value for that last item
            row_list.append(lookup[lookup_key])
            # put the row back in it's original state
            output_for_this_row = ",".join(row_list) + "\n"

        output_list.append(output_for_this_row)


with open('output-big-data.txt', 'wb') as output_file:
    for line in output_list:
        output_file.write("{}".format(line))

我的评论非常彻底,所以它应该是非常明显的。

根据您问题中的文件,我已按顺序命名:input-big-data.txtlookup.csvoutput-big-data.csv

这是我的例子的输出:

@relation 'filename'
@attribute "place" string
@attribute "institution" string
@attribute "food" string
@attribute "book" string

@data
3.8,6,0,0,church,1
86.3,0,63.1,0,man,1
0,0,0,37,woman,0

H个,
亚伦

答案 1 :(得分:0)


如下所述,python可以非常简单地解决这个问题,正如我在此博客上找到并使用的解决方案所证明的那样:http://margerytech.blogspot.it/2011/03/python-appending-column-to-end-of-tab.html

这不是命令行参数(正如我所指出的那样我想在问题中使用),但它解决了问题所在。