3

CSV ファイル (ヘッダー付き) を取得し、Ruby を使用して解析する方法に取り組んでいますが、CSV.parse特定の列のみを保存したいと考えています。

CSV は次のようになります。

NAME,SUPERNET_IP,POP_NAME,ADDRESS_BLOCK_START,ADDRESS_BLOCK_END,Service,ISP Service ID,WCC,DUNSID
Retail,186.43.168.0,text1,186.43.168.0,186.43.175.255,XYZ,XYZB00090095,Enabled,227015716
Retail,186.57.80.0,text2,186.57.80.0,186.57.87.255,XYZ,XYXB00090095,Enabled,227015716

保持したいフィールドは次のとおりです。

POP_NAME,ADDRESS_BLOCK_START,ADDRESS_BLOCK_END,WCC

次のような特定のヘッダー名で CSV を解析する方法はありますか。

mycsv = CSV.parse(csv_data, {:headers => true, (list of headers to keep here) })

csv_dataこの例では、上記の例の CSV から形成された文字列を想定しています。

その場しのぎとして、私はCSVを配列の配列に変換しているだけですが、それは私が求めているものではありません。私はそれをCSVオブジェクトとして保持したいと思います。

myreturnedcsv = []
mycsv = CSV.parse(csv_data, {:headers => true, })
mycsv.each do |row|
  myreturnedcsv.push([row[2], row[3], row[4],row[7]])
end
4

3 に答える 3

6

smarter_csvgem/parserをお試しください。これには、入力の「列」を無視する機能があります (列を削除します) https://github.com/tilo/smarter_csv

于 2012-09-18T11:47:13.727 に答える
2

stdlib のみを使用するとCSV::Table、(デフォルトの混合モードではなく) 列モードでオブジェクトを操作できます。列モードでは、反復メソッドは、列名とその列の値の配列を含む 2 つの要素タプルを生成します。

それを念頭に置いて、次のように書くことができます。

# column names to keep
columns_to_keep = %w(POP_NAME ADDRESS_BLOCK_START ADDRESS_BLOCK_END WCC)

# get the data
mycsv = CSV.parse(csv_data, :headers => true)

# change to column mode, filter by column name and change back to default
# mode of operation
mycsv.by_col!.delete_if do |col_name, col_values|
  !columns_to_keep.include?(col_name)
end.by_col_or_row!   

最後のステップはオプションであり、通常どおり (行ごとに) 反復できるデフォルト モードでテーブル オブジェクトを残すだけです。

大規模なデータセットを処理するときに、このアプローチがパフォーマンス/メモリの問題に悩まされる可能性があるかどうかは、実際にはわかりません。

行/列/混合アクセスの詳細については、CSV::Tableのドキュメントを参照してください。

それが役に立てば幸い。

于 2012-09-18T14:14:25.803 に答える
0

いくつかの配列スライスを実行します。

require 'csv'

csv_data = <<EOT
NAME,SUPERNET_IP,POP_NAME,ADDRESS_BLOCK_START,ADDRESS_BLOCK_END,Service,ISP Service ID,WCC,DUNSID
Retail,186.43.168.0,text1,186.43.168.0,186.43.175.255,XYZ,XYZB00090095,Enabled,227015716
Retail,186.57.80.0,text2,186.57.80.0,186.57.87.255,XYZ,XYXB00090095,Enabled,227015716
EOT

data = []
CSV.parse(csv_data) do |row|
  data << [ *row[2 .. 4], row[-2] ]
end

require 'pp'
pp data

どちらが返されますか:

[["POP_NAME", "ADDRESS_BLOCK_START", "ADDRESS_BLOCK_END", "WCC"],
["text1", "186.43.168.0", "186.43.175.255", "Enabled"],
["text2", "186.57.80.0", "186.57.87.255", "Enabled"]]

コードが何をしているかを簡単に確認できるように、CSV にヘッダーを返させます。通常のオプションを使用してヘッダーをオフにしnewます。

于 2012-09-18T20:01:27.210 に答える