アプリ版:「スタンプのみでお礼する」機能のリリースについて

お世話になります。
pythonあるいはrubyでの出現数の数え方について教えてください。
やりたい事としては、エクセルでいうとcountifのようなことで、現在の文字列は今までに何回出現したのかというのを調べたいです。
例えば
before_count.txt
というファイルに以下のようなデータがあったとすると
_____
あか
だいだい
きいろ
みどり
あお
あい
むらさき
あか
きいろ
みどり
あか
あお
むらさき
あか
______

結果が
after_count.txt
というようなファイルで
____________
あか 1
だいだい 1
きいろ 1
みどり 1
あお 1
あい 1
むらさき 1
あか 2
きいろ 2
みどり 2
あか 3
あお 2
むらさき 2
あか 4
____________
というような感じで出力されてほしいです。
単純に出現回数だけならばpythonで辞書型を使ってcounter関数を使ってカウントさせると、何回該当する文字が出たかはわかりますが、上記の結果のように今何回目というのがわからなくなってしまいます。
上記には例えば、
「あか」
という単語は4回出てきますが、「あか」という文字の横全部に出現数がかかれています。
エクセルでやってはいたのですが、一万行を超えたあたりからぐっと動きが悪くなり長い間エクセルがハングアップ状態になってしまいます。
欲しい結果ファイルとしては、befor_count.txtの並び順のままafter_count.txtの2列目に現在の出現回数が表示したものです。組み方を教えてください。

質問者からの補足コメント

  • すみません。pythonのバージョンは3を使っております。
    エクセルに関しての記述が不味かったです。一万行を越えたあたりからでしれ、データ数は20万を越えることがざらにありまして。

    vbaでのScripting.Dictionary構文は知りませんでした。これについても調べてみます。そしてwibdows環境の方がありがたいです。

    No.2の回答に寄せられた補足コメントです。 補足日時:2018/10/04 00:16

A 回答 (4件)

こんなんでは?

「pythonでの数のカウント方法について」の回答画像1
    • good
    • 0
この回答へのお礼

ご返信ありがとうございます。明日、実験室に戻ったときに実行してみます。

お礼日時:2018/10/04 00:18

1.pythonのバージョンは2でしょうか、それとも3でしょうか?


2.>>エクセルでやってはいたのですが、一万行を超えたあたりからぐっと動きが悪くなり長い間エクセルがハングアップ状態になってしまいます。
ということですが、pythonの辞書に相当する、vbaのScripting.Dictionaryは使用されましたか。
Scripting.Dictionaryを使用すれば1万行程度は全く問題ないはずですが。
3.pythonはバージョンが不明なので、とりあえずruby(1.9以上)のスクリプトを提示します。
before_count.txtはシフトJISコードが前提、Windowsでの動作前提です。
-----------------------------------------------------------
# coding:WINDOWS-31J
#
dic = Hash.new
File.open("before_count.txt") do |file|
while line = file.gets
line.chomp!
if dic.key?(line) == TRUE
dic[line] += 1
else
dic[line] = 1
end
end
end
dic.each do |key,value|
print key," ",value,"\n"
end
この回答への補足あり
    • good
    • 0
この回答へのお礼

ありがとうございます。
pythonは2と3とで互換性に乏しいところがありますね。ご指摘感謝します。自分の環境はpython3です。明日、実験室に戻ったときに実行してみます。

お礼日時:2018/10/04 00:22

python3のコードを下記URLに書きました。


https://ideone.com/My0sl3

vbaのコードです。20万行で4,5秒でした。
---------------------------------
Option Explicit
Public Sub テキスト読み込み()
Dim fname As String
Dim out_fname As String
Dim fileNo As Long
Dim out_fileNo As Long
Dim text As String
Dim data As Variant
Dim dicT As Object
Set dicT = CreateObject("Scripting.Dictionary")
'ファイル名の完全パスを作成
fname = "D:\goo\data\before_count.txt"
out_fname = "D:\goo\data\after_count.txt"
If Dir(fname) = "" Then
MsgBox (fname & "は存在しません。")
Exit Sub
End If
out_fileNo = FreeFile '空き番号取得&オープン
Open out_fname For Output As #out_fileNo
fileNo = FreeFile '空き番号取得&オープン
Open fname For Input As #fileNo
'ファイル終端まで読み込む
Do Until EOF(fileNo)
Line Input #fileNo, text
If dicT.exists(text) = False Then
dicT(text) = 0
End If
dicT(text) = dicT(text) + 1
Print #out_fileNo, text & " " & CStr(dicT(text))
Loop
Close #fileNo
Close #out_fileNo
'成功終了
MsgBox ("完了")
End Sub
    • good
    • 0
この回答へのお礼

pythonのコードを実行した結果、60万行のファイルも一瞬で処理してもらえました。本当にありがとうございます。
VBAの方も便利なので、python3をインストールしていないコンピュータでも実施できます。
ベストアンサーにさせていただきます。

お礼日時:2018/10/04 19:31

No3です。


Pythonのスクリプトはutf-8で記述してください。
before_count.txtが存在するディレクトリ下にこのスクリプトを作成し、そこで実行してください。
before_count.txtの文字コードはSHIFT_JISが前提です。

vba使用時の注意事項です。
このマクロは標準モジュールに登録してください。
fname = "D:\goo\data\before_count.txt"
out_fname = "D:\goo\data\after_count.txt"
については、あなたの環境にあわせて適切に設定してください。
before_count.txtの文字コードはSHIFT_JISが前提です。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!