2016-04-06 8 views
-1

百万レコードの日付範囲が異なる列を持つCSVファイルがあります。たとえば、次のようなものがあります。 2004-2016; 1980-2016; 1991-2006; 2000-2012; 1998年 - 2011年Pythonでさまざまな日付間隔のセットから最も頻繁に発生する日付間隔を調べる

これらのすべてのレコードで最も一般的な3,5または7年の範囲を調べたい場合、これをPythonでどのようにしますか?いくつかのレコードが削除されても問題はありませんが、7年の頻度または10年間の頻度がすべての範囲で最も一般的であるかどうかを調べようとしています。助けてもらえますか?

+0

どのようにデータを読み込みますか? '['2004-2016'、 '1980-2016'、...]'のようなリストで? – Reti43

+1

正確に何が助けを必要としますか?あなたは何を試していますか、どこに詰まっていますか?まだコードを書いていませんか? –

答えて

0
  • 解析ファイル。 2要素タプル:((2004, 2016), (1980-2016), ...)を取得します。
  • 違いに変換:(12, 36, ...)
  • Counterオブジェクトをこのsequnceで作成し、most_commonメソッドを呼び出します。
-1

シーケンスを個々の範囲に分割します。結果のシーケンスdiffを呼び出すと仮定します。

from collections import Counter 

diff = ["2004-2016", "1980-2016", "1991-2006", "2000-2012", "1998 - 2011"] 

diff_frequency = Counter(map(lambda x: abs(eval(x)), diff)).most_common() 

most_common_diff = diff_frequency[0] 
1

あなたはこれを処理するためにcollections.Countercollections.defaultdictを使用することができます。 defaultdictは年の数でグループに日付範囲を使用し、Counterは年のその数の範囲の文字列の数を追跡します:あなたが最も一般的な範囲の文字列を知りたい場合は

from collections import defaultdict, Counter 

year_ranges = defaultdict(Counter) 

s = '2004-2016; 1980-2016; 1991-2006; 2000-2012; 1998 - 2011; 2004-2016' 
for start, end in [r.split('-') for r in s.split('; ')]: 
    start, end = int(start), int(end) 
    year_ranges[end-start].update(['{}-{}'.format(start, end)]) # update counter for normalised range string 

>>> print(year_ranges) 
defaultdict(<class 'collections.Counter'>, {36: Counter({'1980-2016': 1}), 12: Counter({'2004-2016': 1, '2000-2012': 1}), 13: Counter({'1998-2011': 1}), 15: Counter({'1991-2006': 1})}) 

年の範囲12:

>>> year_ranges[12].most_common(1) 
[('2004-2016', 2)] 

等しい年数の範囲を表す複数の範囲文字列があるケースをどのように処理するかはわかりません。

+0

@ Reti43:信頼できないデータでは 'eval'が危険です。また、それは遅く、100万レコードあります。私が示す方法には、日付範囲文字列を数える前に正規化するという利点もあります。たとえば、「1998 - 2011」と「1998-2011」は同じと見なされます。 – mhawke

+0

@ Reti43: 'try'文はどのようにして任意のコードの実行を阻止しますか?入力が悪意のあるが、 'eval()'が実行できる有効なコードであれば、例外は発生しません。データに 'os.system( 'rm -rf/tmp')'(または悪い)が含まれていたらどうなりますか?一般的に、 'eval()'を使うのは悪い考えです。そして、それは私が示す直接的な文字列の操作よりも4〜6倍遅くなります。また、入力文字列を正規化して合理的な集計を得る必要があります。 – mhawke

+0

私は 'eval()'を主張していません。あなたはまたそれがより速いという良い点を作った。しかし、入力が間違っている可能性があると仮定すると、 'int()'は失敗する可能性があります。 – Reti43

関連する問題