2

したがって、次のようなlaaaaaaaargeファイルがあります。

Item|Cost1|Cost2
Pizza|50|25
Sugar|100|100
Spices|100|200
Pizza|100|25
Sugar|200|100
Pizza|50|100

Cost1特定のアイテムのすべての とを追加Cost2して、マージされた出力を生成したいと考えています。

これを行うためのPythonコードを作成しました。

item_dict = {}
for line in file:
    fields = line.split('|')
    item = fields[0]
    cost1 = fields[1]
    cost2 = fields[2]
    if item_dict.has_key(item):
        item_dict[item][0] += int(cost1)
        item_dict[item][1] += int(cost2)
    else:
        item_dict[item] = [int(cost1),int(cost2)]

for key, val in item_dict.items():
    print key,"|".join(val)

awkまたは他の魔法を使用して、これを非常に効率的かつ迅速に行う方法はありますか?

または、Python をよりエレガントで高速にすることはできますか?

期待される出力

Pizza|200|150
Sugar|300|200
Spices|100|200
4

3 に答える 3

10

このようなもの...

$ awk 'BEGIN{OFS=FS="|"}
  NR>1 {cost1[$1]+=$2; cost2[$1]+=$3} 
  END{ for (i in cost1) print i, cost1[i], cost2[i]}' file
Sugar|300|200
Spices|100|200
Pizza|200|150

説明

  • BEGIN{OFS=FS="|"}(入力と出力) フィールドセパレータを に設定します|
  • NR>11 より大きい行番号に対していくつかのアクションを実行することを意味します。このようにして、ヘッダーをスキップします。
  • cost1およびcost2は、インデックスが最初のフィールドであり、その値がその時点までの合計である配列です。
  • END {}ファイル全体を読み取った後に行うことです。これは、配列をループして値を出力することで構成されます。
于 2013-09-30T15:19:51.957 に答える
4
awk '
    BEGIN { FS=OFS="|" }
    NR==1 { expectedNF = NF; next }
    NF != expectedNF { print "Fix your #%@#&! data, idiot!"; exit 1 }'
    {
        items[$1]
        for (c=2;c<=NF;c++)
            cost[$1,c] += $c
    } 
    END {
        for (i in items) {
            printf "%s", i
            for (c=2;c<=NF;c++)
                printf "%s%s", OFS, cost[i,c]
            print ""
        }
    }
' file

必要に応じて、自由に 1 行または 2 行に圧縮してください。

于 2013-09-30T15:30:16.903 に答える
1

実際には、私はフェドルキがしたことをしたでしょう。ただし、完全を期すために、このpythonスクリプトは元のスクリプトよりも高速である必要があります。

#!/usr/bin/env python

import fileinput

item_dict = {}

for line in fileinput.input():
    if not fileinput.isfirstline():
        fields = line.strip().split('|')
        item = fields[0]
        cost1 = int(fields[1])
        cost2 = int(fields[2])
        try:
            item_dict[item][0] += cost1
            item_dict[item][1] += cost2
        except KeyError:
            item_dict[item] = [cost1, cost2]

for key, val in item_dict.items():
    print "%s|%s|%s" % (key,val[0],val[1])

スクリプトを次のようなファイルに保存し、実行可能にして次のようsumcolsに実行chmod +x sumcolsします。

$ ./sumcols file
Spices|100|200
Sugar|300|200
Pizza|200|150
于 2013-09-30T15:40:27.423 に答える