Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/360.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 用匹配的键组合线_Python_Linux_Perl_Awk - Fatal编程技术网

Python 用匹配的键组合线

Python 用匹配的键组合线,python,linux,perl,awk,Python,Linux,Perl,Awk,我有一个具有以下结构的文本文件 ID,operator,a,b,c,d,true WCBP12236,J1,75.7,80.6,65.9,83.2,82.1 WCBP12236,J2,76.3,79.6,61.7,81.9,82.1 WCBP12236,S1,77.2,81.5,69.4,84.1,82.1 WCBP12236,S2,68.0,68.0,53.2,68.5,82.1 WCBP12234,J1,63.7,67.7,72.2,71.6,75.3 WCBP12234,J2,68.6,6

我有一个具有以下结构的文本文件

ID,operator,a,b,c,d,true
WCBP12236,J1,75.7,80.6,65.9,83.2,82.1
WCBP12236,J2,76.3,79.6,61.7,81.9,82.1
WCBP12236,S1,77.2,81.5,69.4,84.1,82.1
WCBP12236,S2,68.0,68.0,53.2,68.5,82.1
WCBP12234,J1,63.7,67.7,72.2,71.6,75.3
WCBP12234,J2,68.6,68.4,41.4,68.9,75.3
WCBP12234,S1,81.8,82.7,67.0,87.5,75.3
WCBP12234,S2,66.6,67.9,53.0,70.7,75.3
WCBP12238,J1,78.6,79.0,56.2,82.1,84.1
WCBP12239,J2,66.6,72.9,79.5,76.6,82.1
WCBP12239,S1,86.6,87.8,23.0,23.0,82.1
WCBP12239,S2,86.0,86.9,62.3,89.7,82.1
WCBP12239,J1,70.9,71.3,66.0,73.7,82.1
WCBP12238,J2,75.1,75.2,54.3,76.4,84.1
WCBP12238,S1,65.9,66.0,40.2,66.5,84.1
WCBP12238,S2,72.7,73.2,52.6,73.9,84.1
每个
ID
对应于一个由操作员多次分析的数据集。i、 e
J1
J2
是操作员J的第一次和第二次尝试。测量
a
b
c
d
使用4种稍有不同的算法来测量真实值位于
true
列中的值

我想做的是创建3个新的文本文件,比较
J1
vs
J2
S1
vs
S2
J1
vs
S1
的结果。
J1
vs
J2
的输出示例:

ID,operator,a1,a2,b1,b2,c1,c2,d1,d2,true
WCBP12236,75.7,76.3,80.6,79.6,65.9,61.7,83.2,81.9,82.1
WCBP12234,63.7,68.6,67.7,68.4,72.2,41.4,71.6,68.9,75.3
foreach i (`more unique_ids`)
    grep $i test.txt | egrep 'J[1-2]' | sort -t',' -k2
end
其中
a1
J1
等的测量
a

另一个例子是针对
S1
S2

ID,operator,a1,a2,b1,b2,c1,c2,d1,d2,true
WCBP12236,77.2,68.0,81.5,68.0,69.4,53.2,84.1,68.5,82.1
WCBP12234,81.8,66.6,82.7,67.9,67.0,53,87.5,70.7,75.3
ID不会按字母数字顺序排列,也不会为同一ID对运算符进行集群。我不确定如何最好地完成此任务—使用linux工具或perl/python之类的脚本语言

我最初使用linux的尝试很快就失败了

首先查找所有唯一ID(已排序)

在这些ID中循环并排序
J1
J2

ID,operator,a1,a2,b1,b2,c1,c2,d1,d2,true
WCBP12236,75.7,76.3,80.6,79.6,65.9,61.7,83.2,81.9,82.1
WCBP12234,63.7,68.6,67.7,68.4,72.2,41.4,71.6,68.9,75.3
foreach i (`more unique_ids`)
    grep $i test.txt | egrep 'J[1-2]' | sort -t',' -k2
end
这给了我排序的数据

WCBP12234,J1,63.7,67.7,72.2,71.6,75.3
WCBP12234,J2,68.6,68.4,41.4,68.9,80.4
WCBP12236,J1,75.7,80.6,65.9,83.2,82.1
WCBP12236,J2,76.3,79.6,61.7,81.9,82.1
WCBP12238,J1,78.6,79.0,56.2,82.1,82.1
WCBP12238,J2,75.1,75.2,54.3,76.4,82.1
WCBP12239,J1,70.9,71.3,66.0,73.7,75.3
WCBP12239,J2,66.6,72.9,79.5,76.6,75.3
我不知道如何重新排列这些数据以获得所需的结构。我尝试在
foreach
循环
awk'BEGIN{RS=“\n\n”}{print$1,$3,$10,$4,$11,$5,$12,$6,$13,$7}中的


有什么想法吗?我确信使用
awk
可以以一种不那么麻烦的方式完成这项工作,尽管使用合适的脚本语言可能更好。

您可以使用Perl csv模块提取字段,然后将其存储在散列中,其中ID是主键,第二个字段是辅助键,所有字段都作为值存储。然后,做任何你想做的比较都应该是微不足道的。如果要保留行的原始顺序,可以在第一个循环中使用数组

use strict;
use warnings;
use Text::CSV;

my %data;
my $csv = Text::CSV->new({
            binary => 1,      # safety precaution
            eol    => $/,     # important when using $csv->print()
    });
while ( my $row = $csv->getline(*ARGV) ) {
    my ($id, $J) = @$row;   # first two fields
    $data{$id}{$J} = $row;  # store line
}
Python方式:

import os,sys, re, itertools
info=["WCBP12236,J1,75.7,80.6,65.9,83.2,82.1",
  "WCBP12236,J2,76.3,79.6,61.7,81.9,82.1",
  "WCBP12236,S1,77.2,81.5,69.4,84.1,82.1",
  "WCBP12236,S2,68.0,68.0,53.2,68.5,82.1",
  "WCBP12234,J1,63.7,67.7,72.2,71.6,75.3",
  "WCBP12234,J2,68.6,68.4,41.4,68.9,80.4",
  "WCBP12234,S1,81.8,82.7,67.0,87.5,75.3",
  "WCBP12234,S2,66.6,67.9,53.0,70.7,72.7",
  "WCBP12238,J1,78.6,79.0,56.2,82.1,82.1",
  "WCBP12239,J2,66.6,72.9,79.5,76.6,75.3",
  "WCBP12239,S1,86.6,87.8,23.0,23.0,82.1",
  "WCBP12239,S2,86.0,86.9,62.3,89.7,82.1",
  "WCBP12239,J1,70.9,71.3,66.0,73.7,75.3",
  "WCBP12238,J2,75.1,75.2,54.3,76.4,82.1",
  "WCBP12238,S1,65.9,66.0,40.2,66.5,80.4",
  "WCBP12238,S2,72.7,73.2,52.6,73.9,72.7" ]

def extract_data(operator_1, operator_2):
    operator_index=1
    id_index=0
    data={}
    result=[]
    ret=[]
    for line in info:
        conv_list=line.split(",")
        if len(conv_list) > operator_index and ((operator_1.strip().upper() == conv_list[operator_index].strip().upper()) or (operator_2.strip().upper() == conv_list[operator_index].strip().upper()) ):
            if data.has_key(conv_list[id_index]):
                iters = [iter(conv_list[int(operator_index)+1:]), iter(data[conv_list[id_index]])]
                data[conv_list[id_index]]=list(it.next() for it in itertools.cycle(iters))
                continue
            data[conv_list[id_index]]=conv_list[int(operator_index)+1:]
    return data

ret=extract_data("j1", "s2")
print ret
O/p:

{'WCBP12239':['70.9','86.0','71.3','86.9','66.0','62.3','73.7','89.7','75.3','82.1'],'WCBP12238':['72.7','78.6','73.2','79.0','52.6','56.2','73.9','82.9','82.1','WCBP12234':['66.6','63.7','67.9','67.7','67.7','53.0','72.2','70.7','71.6','WCBP12236'][68.0,75.7,68.0,80.6,53.2,65.9,68.5,83.2,82.1,82.1']


我没有像TLP那样使用Text::CSV。如果您需要,您可以,但对于本例,我认为由于字段中没有嵌入逗号,所以我对“,”进行了简单的拆分。此外,两个运算符的真实字段都会列出(而不是仅列出1),因为我认为最后一个值的特殊情况会使解决方案复杂化

#!/usr/bin/perl
use strict;
use warnings;
use List::MoreUtils qw/ mesh /;

my %data;

while (<DATA>) {
    chomp;
    my ($id, $op, @vals) = split /,/;
    $data{$id}{$op} = \@vals;
}

my @ops = ([qw/J1 J2/], [qw/S1 S2/], [qw/J1 S1/]);

for my $id (sort keys %data) {
    for my $comb (@ops) {
        open my $fh, ">>", "@$comb.txt" or die $!;
        my $a1 = $data{$id}{ $comb->[0] };
        my $a2 = $data{$id}{ $comb->[1] };
        print $fh join(",", $id, mesh(@$a1, @$a2)), "\n";
        close $fh or die $!;
    }   
}

__DATA__
WCBP12236,J1,75.7,80.6,65.9,83.2,82.1
WCBP12236,J2,76.3,79.6,61.7,81.9,82.1
WCBP12236,S1,77.2,81.5,69.4,84.1,82.1
WCBP12236,S2,68.0,68.0,53.2,68.5,82.1
WCBP12234,J1,63.7,67.7,72.2,71.6,75.3
WCBP12234,J2,68.6,68.4,41.4,68.9,75.3
WCBP12234,S1,81.8,82.7,67.0,87.5,75.3
WCBP12234,S2,66.6,67.9,53.0,70.7,75.3
WCBP12239,J1,78.6,79.0,56.2,82.1,82.1
WCBP12239,J2,66.6,72.9,79.5,76.6,82.1
WCBP12239,S1,86.6,87.8,23.0,23.0,82.1
WCBP12239,S2,86.0,86.9,62.3,89.7,82.1
WCBP12238,J1,70.9,71.3,66.0,73.7,84.1
WCBP12238,J2,75.1,75.2,54.3,76.4,84.1
WCBP12238,S1,65.9,66.0,40.2,66.5,84.1
WCBP12238,S2,72.7,73.2,52.6,73.9,84.1
S1 S2.txt

WCBP12234,81.8,66.6,82.7,67.9,67.0,53.0,87.5,70.7,75.3,75.3
WCBP12236,77.2,68.0,81.5,68.0,69.4,53.2,84.1,68.5,82.1,82.1
WCBP12238,65.9,72.7,66.0,73.2,40.2,52.6,66.5,73.9,84.1,84.1
WCBP12239,86.6,86.0,87.8,86.9,23.0,62.3,23.0,89.7,82.1,82.1
J1 S1.txt

WCBP12234,63.7,81.8,67.7,82.7,72.2,67.0,71.6,87.5,75.3,75.3
WCBP12236,75.7,77.2,80.6,81.5,65.9,69.4,83.2,84.1,82.1,82.1
WCBP12238,70.9,65.9,71.3,66.0,66.0,40.2,73.7,66.5,84.1,84.1
WCBP12239,78.6,86.6,79.0,87.8,56.2,23.0,82.1,23.0,82.1,82.1
更新:要仅获取1个真值,for循环可以这样编写:

for my $id (sort keys %data) {
    for my $comb (@ops) {
        local $" = '';
        open my $fh, ">>", "@$comb.txt" or die $!;
        my $a1 = $data{$id}{ $comb->[0] };
        my $a2 = $data{$id}{ $comb->[1] };
        pop @$a2;
        my @mesh = grep defined, mesh(@$a1, @$a2);
        print $fh join(",", $id, @mesh), "\n";
        close $fh or die $!;
    }   
}

更新:在grep expr中为测试添加了“defined”,因为这是正确的方法(而不是只测试“$\”,它可能是0,并且被grep错误地排除在列表之外).

在您的第二个代码块中,您是否打算让
82.1
只出现一次?抱歉,重新阅读问题,注意到它是“真”值。另外,为什么您需要J1 v J2两次?icedwater指的是表示您希望输入类型对应的
J1 vs J2、S1 vs S2和J1 vs J2的结果的部分。我的意思是
J1 vs J2
S1 vs S2
J1 vs S1
在您的文件中,同一数据集ID可以有不同的
true
值?例如,
WCBP12234