処理テキストからフラットではなくファイル情報を抽出してまでしていたことが明らかになった*平坦なファイル)

StackOverflow https://stackoverflow.com/questions/2264504

質問

私は縦断データセットを生成するコンピュータシミュレーションで表すことができる以下のテーブル('var'は変数):

time subject var1 var2 var3
t1   subjectA  ...
t2   subjectB  ...

subject   name
subjectA  nameA
subjectB  nameB

しかし、ファイルに書き込みデータファイル形式、例えば次のようなもの:

time t1 
  description
subjectA nameA
  var1 var2 var3
subjectB nameB
  var1 var2 var3
time t2
  description
subjectA nameA
  var1 var2 var3
subjectB nameB
  var1 var2 var3
...(and so on)

いなどを進めています(python)スクリプトをこの出力データを平らなテキストファイルができるように取り込むことによりR、python、SQL、awk/grepで抽出情報のタイプの情報から望む単一クエリー(アプリケーションでの表記、その後のデータに変換し表示すと以下のようになります。

SELECT var1, var2, var3 FROM datatable WHERE subject='subjectB'

だが、より効率的なソリューションとしてそれぞれのデータファイルのやりとりができ~100MBれない何百人もの)を作のテキストファイルには時間がかかるとアップ追加のハードドライブスペースと冗長な情報です。理想的には、私たちと交流し、元のデータセットに直接情報を抽出できるまいを行わずに平坦なテキストファイル...はありまawk/perl解決のために次のような課題を解決するのは簡単?私は非常に堪能なテキスト処理はpythonが討論やプレゼンテーションの能力awkは基礎としていませんのperl;かまたはその他のドメイン固有のツールを提供できるより良い解決策です。

よろしく!

追記: ねん!誠に申し訳ございませんができない皆さんの回答 @FM:感謝。私のPythonスクリプトに似たコードなしのフィルタリングする。が組織する。@PPったので、既に堪能grepがそうではありません!これはも...私greppingが困難になりの時間を出力するか失敗したとして含める可能抽出のシナリオは私の例ですね。これはまさに私にぴったりの悪い).@ghostdog74:ここには幻想的---が変更に引越しの予定が決まったら'subjectAではなかったか...もう読み上りawk一方で、できればと思grokます。@weismat:ものを記載しています。@S.Lott:これは非常に優雅で柔軟なかったのでうためのpython(ic)溶液にこう綺麗に、parse、フィルタ出力の枠組みを提案するPP、柔軟に対応する異なるクエリを抽出すことで、さまざまなタイプの情報からこの階層ファイルです。

再度、皆様に感謝いたし-ありがとうございました。

役に立ちましたか?

解決

これはPythonの発電機です。

def read_as_flat( someFile ):
    line_iter= iter(someFile)
    time_header= None
    for line in line_iter:
        words = line.split()
        if words[0] == 'time':
            time_header = [ words[1:] ] # the "time" line
            description= line_iter.next()
            time_header.append( description )
        elif words[0] in subjectNameSet:
            data = line_iter.next()
            yield time_header + data

このようなリファレンスマニュアルの反復子

for time, description, var1, var2, var3 in read_as_flat( someFile ):
    etc.

他のヒント

だいたいでvar1,var2,var3にマッチングが特定された次のことを試してみてくださいコマンド:


  grep -A 1 'subjectB'

-A 1 コマンドライン引数に指示grepする場合には、線と線の後にはデフォルトパラメータと合致し線(この場合、変数に来らないものとします。

するために使用 -E オプションをgrep検索用の正規表現とアンカーを検索最初の例 grep -A 1 -E '^subjectB').

最後に、出力ではのラインと可変線ます。いを非表示にします件名:


  grep -A 1 'subjectB' |grep -v 'subjectB'

としたいことがあるでしょう過程変数のライン:


  grep -A 1 'subjectB' |grep -v 'subjectB' |perl -pe 's/ /,/g'

最良のオプションを変更コンピュータシミュレーションを矩形を出力します。と仮定できないが、こちらのアプローチ:

できるようにデータを利用するR,SQL等変換する必要がありまからの階層的に矩形があることが明らかになり持っている人は、手続きをすれば、パーサに変換する機能の全ファイル矩形のデータセットは、すでにあります。次のステップでは、追加の柔軟性をパーサーでフィルターの出は不要なデータを記録です。ずにファイルをコンバータの高いデータを抽出する。

下記の例はPerlいて頂きますが、同様のこと。の考え方を維持することを清潔に分離(a)の解析、(b)フィルタリング、(c)出力に出力します。そのように、柔軟な環境での追加が簡単なフィルタリングまたは出力の方法によっては、即時データを延す。ように設定することもできます、フィルタリング手法の受け入れパラメータのいずれかからのコマンドラインや設定ファイル)を柔軟に対応する

use strict;
use warnings;

read_file($ARGV[0], \&check_record);

sub read_file {
    my ($file_name, $check_record) = @_;
    open(my $file_handle, '<', $file_name) or die $!;
    # A data structure to hold an entire record.
    my $rec = {
        time => '',
        desc => '',
        subj => '',
        name => '',
        vars => [],
    };
    # A code reference to get the next line and do some cleanup.
    my $get_line = sub {
        my $line = <$file_handle>;
        return unless defined $line;
        chomp $line;
        $line =~ s/^\s+//;
        return $line;
    };
    # Start parsing the data file.
    while ( my $line = $get_line->() ){
        if ($line =~ /^time (\w+)/){
            $rec->{time} = $1;
            $rec->{desc} = $get_line->();
        }
        else {
            ($rec->{subj}, $rec->{name}) = $line =~ /(\w+) +(\w+)/;
            $rec->{vars} = [ split / +/, $get_line->() ];

            # OK, we have a complete record. Now invoke our filtering
            # code to decide whether to export record to rectangular format.
            $check_record->($rec);
        }
    }
}

sub check_record {
    my $rec = shift;
    # Just an illustration. You'll want to parameterize this, most likely.
    write_output($rec)
        if  $rec->{subj} eq 'subjectB'
        and $rec->{time} eq 't1'
    ;
}

sub write_output {
    my $rec = shift;
    print join("\t", 
        $rec->{time}, $rec->{subj}, $rec->{name},
        @{$rec->{vars}},
    ), "\n";
}

の場合は怠惰といRAMという仕事は、RAMディスクの代わりにファイルシステムとして長いお客様のご要望に応じています。
るとは思いませんPerl又はawkでより早く、よPythonの場合は記録の現在のアルゴリズムの異なる言語です。

awk '/time/{f=0}/subjectB/{f=1;next}f' file
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top