【问题标题】:script to get the max from column based on other column values根据其他列值从列中获取最大值的脚本
【发布时间】:2014-04-23 09:40:26
【问题描述】:

我需要一个脚本来读取一个 csv 文件(orig.csv)并输出一个重新格式化的 csv 文件(format.csv)

原始 csv 文件将如下所示:

Time,Label,frame,slot,SSN,Board,BT,SRN,LabelFrame,SRNAME,LabelID,Integrity,MAX_val
2014-03-17,lableA,1,8,0,,SPUB,1,NNN,NNN,1,100%,60
2014-03-17,lableA,2,22,0,,GOUC,2,NNN02,NNN02,1,100%,
2014-03-17,lableB,2,8,0,,CCCB,2,NNN02,NNN02,1,100%,59
2014-03-17,lableB,1,2,4,,CCCB,1,NNN,NNN,1,100%,48
2014-03-17,lableB,1,0,6,,CCCB,1,NNN,NNN,1,100%,59
2014-03-17,lableC,2,6,0,,SCUA,2,NNN02,NNN02,1,100%,55
2014-03-17,lableD,2,4,1,,CCCB,2,NNN02,NNN02,1,100%,59
2014-03-17,lableD,0,2,7,,CCCB,0,MPS,MPS,1,100%,46
2014-03-17,lableD,1,4,3,,CCCA,1,NNN,NNN,1,100%,43
2014-03-17,lableE,2,2,7,,CCCB,2,NNN02,NNN02,1,100%,58

重新格式化将通过 orig csv 文件并从 column2(Label) 中获取所有唯一名称,并从 column 13(MAX_val) 中获取相应的最大值,请参见下面的示例。(EG lableA-E 是有趣的,而对于 lableB,[59,48,59] 的最大值是有趣的)我还希望它尽可能满足动态 orig.csv 文件。

报告的 csv 文件将如下所示:

Time,Label,frame,slot,SSN,Board,BT,SRN,LabelFrame,SRNAME,LabelID,Integrity,MAX_val
2014-03-17,lableA,1,8,0,,CCCB,1,NNN,NNN,1,100%,60
2014-03-17,lableB,2,8,0,,CCCB,2,NNN02,NNN02,1,100%,59
2014-03-17,lableC,2,6,0,,SCUA,2,NNN02,NNN02,1,100%,55
2014-03-17,lableD,2,4,1,,CCCB,2,NNN02,NNN02,1,100%,59
2014-03-17,lableE,2,2,7,,CCCB,2,NNN02,NNN02,1,100%,58

注意:我是脚本新手,所以不确定用什么语言编写它的最佳语言,但我一直在考虑 bash、shell、perl,但对其他人开放。

编辑:: 这就是我提取 csv 数据的方式

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>D3: Loading data from a CSV file</title>
        <script type="text/javascript" src="d3/d3.v3.js"></script>
    </head>
    <body>
        <script type="text/javascript">

            d3.csv("XPU max load_format1(XPU load).csv", function(data) {
                console.log(data);
            });

        </script>
    </body>
</html>

【问题讨论】:

  • 显示用于提取 csv 数据的代码。
  • 当多条记录共享相同的 col13 最高值时会发生什么?
  • 你的第二个数据行(文件的第三行)有一个空列 13. 这种情况下怎么办?
  • @Aaron 编辑了我的 Q 来回答你
  • @Kenosis 例如[59,59,58] 那么 59 会很有趣

标签: python perl bash csv max


【解决方案1】:

这是针对您的问题的 Perl 解决方案。它为每个标签的数据散列%data,在MAX_val 中具有最高值。它还在@labels 中保存了一个标签列表,在遇到新标签时跟踪它们,从而保持输出与输入的顺序相同。

正如我在评论中所说,您的数据中有一行第 13 列为空。我添加了将其视为零的代码,如果这是您的帖子中的错误,则这是不必要的。

use strict;
use warnings;

open my $orig_fh,   '<', 'orig.csv'   or die $!;
open my $format_fh, '>', 'format.csv' or die $!;

print $format_fh scalar <$orig_fh>; # Copy header line

my %data;
my @labels;

while (<$orig_fh>) {
  chomp;
  my @fields = split /,/, $_, -1;
  my ($label, $max_val) = @fields[1,12];
  if ( exists $data{$label} ) {
    my $prev_max_val = $data{$label}[12] || 0;
    $data{$label} = \@fields if $max_val and $max_val > $prev_max_val;
  }
  else {
    $data{$label} = \@fields;
    push @labels, $label;
  }
}

for my $label (@labels) {
  print $format_fh join(',', @{ $data{$label} }), "\n";
}

输出

Time,Label,frame,slot,SSN,Board,BT,SRN,LabelFrame,SRNAME,LabelID,Integrity,MAX_val
2014-03-17,lableA,1,8,0,,SPUB,1,NNN,NNN,1,100%,60
2014-03-17,lableB,2,8,0,,CCCB,2,NNN02,NNN02,1,100%,59
2014-03-17,lableC,2,6,0,,SCUA,2,NNN02,NNN02,1,100%,55
2014-03-17,lableD,2,4,1,,CCCB,2,NNN02,NNN02,1,100%,59
2014-03-17,lableE,2,2,7,,CCCB,2,NNN02,NNN02,1,100%,58

【讨论】:

  • Tks,但我只在运行该脚本后才得到第一行。
  • 我已经根据您在问题中显示的数据对其进行了测试。 “第一行”是指标题行吗?您正在使用什么计算机系统?该文件是否来自不同的系统?尝试在chomp; 后面加上print; 语句,看看它在读什么。
  • 是的,我的意思是标题。 windows XP 使用 cygwin。我正在使用来自 m 问题的相同数据。我在chomp; 之后尝试了print;,但没有打印任何内容。提前 tks
  • 可能会为此提出另一个问题,但我怎么能稍微改变它以处理多个名称如“H_*.csv”的文件。 tks
  • 我的多个文件的可能解决方案 Q:here 和 here
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-29
  • 1970-01-01
  • 2021-09-27
  • 1970-01-01
  • 2016-11-30
相关资源
最近更新 更多