質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%

Q&A

解決済

5回答

3994閲覧

カンマ区切りのデータの重複する要素とその値を合計したい

ode

総合スコア25

0グッド

0クリップ

投稿2017/05/28 15:55

閲覧ありがとうございます。

カンマ区切りのデータの重複する要素とその値を合計したいのですが、どのようにすればよいのでしょうか?
とても大きなデータなので、excelでは開けませんでした。

~例~
sample.txt
あああ, 100
いいい, 200
あああ, 300
ううう, 50
いいい, 400


result.txt
あああ, 400
いいい, 600
ううう, 50

このようにしたいです。
どうか助言をよろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答5

0

EXCELで開けない程の巨大なCSVができてしまうと困ってしまいますね・・・というところはさておき、

重複排除した結果の行数がEXCELに読み込める程度のものかつ、EXCELのみを使う条件ならVBAでスクリプトを書いて重複排除しながらシートへ加算するという手もありますが・・・

こうしたテキスト処理だとUnixのawkなどを使えば割と簡単に処理できますのでそれをご紹介します。プログラムという程のものを書かなくても以下のように1行で書けます。WindowsでもGawk for Windowsをインストールすればコマンドプロンプトから同様の手軽さで処理できます。(先頭はawkではなくgawkに変えなければならないかも知れません)

bash

1awk -F, '{v[$1]+=$2}END{for(k in v)print k","v[k]}' sample.txt > result.txt

キー数一万、総行数百万行程度のテキストで試してみましたが1秒程度で終わりました。(Windows10 64bit)

投稿2017/05/28 17:13

KSwordOfHaste

総合スコア18394

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ode

2017/05/28 18:00

ご回答ありがとうございます。 難しく考えていましたが1行ですんでしまうのですね...。 とても勉強になりました。ありがとうございました。
guest

0

既に解決済ではありますが、Elixirで書くと、こんな感じです

なお、下記Elixirコードの説明を、以下URLにて行っています
http://qiita.com/piacere/items/377db38e2c1a7bfd7413

ex

1defmodule HugeAgreegation do 2 def uniq_sum() do 3 result = "sample.txt" 4 |> File.stream! 5 |> Enum.map( &( String.trim( &1 ) ) ) 6 |> Enum.map( &( String.split( &1, ", " ) ) ) 7 |> Enum.map( fn( [ word, num ] ) -> %{ "word" => word, "num" => num } end ) 8 |> Enum.group_by( fn( pair ) -> pair[ "word" ] end, fn( pair ) -> String.to_integer( pair[ "num" ] ) end ) 9 |> Enum.map( fn( pair ) -> { elem( pair, 0 ), Enum.sum( elem( pair, 1 ) ) } end ) 10 |> Enum.map( fn( { word, num_sum } ) -> "#{word}, #{num_sum}\n" end ) 11 File.write( "result.txt", result ) 12 end 13end

100万行のCSVで、約6秒、といったところでしょうか

投稿2017/05/29 16:25

編集2017/05/29 16:43
piacerex

総合スコア51

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ode

2017/05/30 11:49

とても丁寧な解説、本当にありがとうございます。 恥ずかしながら、Elixirとは初対面でしたが、解説のおかげで理解できました。 また何かありましたらどうかよろしくお願い致します。
guest

0

c# であり 汚いソースですが役に立てれば幸いです
using System.Collections.Generic;
using System.IO;
using static System.Console;

namespace ConsoleApp3
{
static class Program
{
static void Main(string[] args)
{
if (args.Length < 1)
return;

List<string> keys = new List<string>(); Dictionary<string, int> dic = new Dictionary<string, int>(); using (StreamReader sr = new StreamReader(args[0])) { string[] rec = sr.ReadLine().Split(','); for (; rec != null; ) { string tango = rec[0]; int count= int.Parse(rec[1]); if (dic.ContainsKey(tango)) dic[tango] += count; else { dic.Add(tango, count); keys.Add(tango); } rec = sr?.ReadLine()?.Split(','); } } foreach(string str in keys) { int count = dic[str]; WriteLine($"{str},{count}"); } ReadLine(); } }

}

投稿2017/05/28 17:11

NaomasaIshikura

総合スコア12

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ode

2017/05/28 18:02

プログラムも載せていただいて、丁寧なご回答ありがとうございます。 C言語は久しく触れていないので難しく思えていましたが、このようにすればよかったのですね...。 参考にさせていただきます。ありがとうございました。
guest

0

Excelタグがついているので、Excelマクロでのコード例

Public Sub SumOutput() Dim CN As Object Dim sSql As String Set CN = CreateObject("ADODB.Connection") With CN .Provider = "Microsoft.ACE.OLEDB.12.0" .Properties("Extended Properties") = "Text;HDR=NO" .ConnectionString = "C:\TEST\" 'ファイルのあるフォルダ .Open End With sSql = "SELECT F1, Sum(F2) INTO [result.txt] FROM [sample.txt] GROUP BY F1;" CN.Execute sSql CN.Close Set CN = Nothing End Sub

投稿2017/05/28 16:48

編集2017/05/28 16:49
hatena19

総合スコア33715

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ode

2017/05/28 17:46

プログラムも載せていただいて、丁寧なご回答ありがとうございます。 早速試してみたのですが、出力されたファイルの文字コードがおかしくなってしまってうまく表示できませんでした。マクロは使用したことがないので対処法がよく分からず、どのようにしたらよいでしょうか?
hatena19

2017/05/28 17:57

元ファイルの文字コードはなんでしょうか。 Shitt-JIS でのテストではうまくいきました。
ode

2017/05/28 18:03

元のファイルはutf-8です。
hatena19

2017/05/28 18:44

utf-8 のファイルでもテストしてみましたが、当方の環境ではうまくいきました。 Windows10 Excel2016 ちなみに、総数100万件、キー1万のサンプルデータで2秒ぐらいでした。
ode

2017/05/28 19:04

そうなのですか、よく分からないですね...。 当方の環境は windows8.1 Excel2010 です。 Excel2010は文字コード変更ができないことが原因なのでしょうか...。
guest

0

ベストアンサー

linuxマシンにsample.txtをコピーして
hoge.awkファイルを作成

$ cat hoge.awk BEGIN{ x = "" } { if ($1 == x) { n = n + $2 } else { if (x != "") { print x "," n } x = $1 n = $2 } } END{ print x "," n }

上記を使ってこんな感じで実行

$ cat sample.txt | tr ',' ' ' | sort -k 1,1 | awk -f hoge.awk >result.txt

投稿2017/05/28 16:40

takasima20

総合スコア7458

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ode

2017/05/28 17:49

プログラムも載せていただいて、丁寧なご回答ありがとうございます。 早速試してみたのですが、統合後のファイルを開いてみても、元のファイルと変わらず統合されませんでした。 この形のプログラムは書いたことがなく、また助言をいただければ幸いです。
ode

2017/05/28 17:57

失礼致しました。 もう一度試してみたところ、しっかりと統合されておりました。 とても助かりました。ありがとうございました。 また何かありましたらどうかよろしくお願いいたします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問