2017-08-30 12 views
0

リスト内の最も頻繁で頻度の低い要素を取得しようとしています。collections.Counterを使用せずに出現回数をカウントする

frequency([13,12,11,13,14,13,7,11,13,14,12,14,14]) 

私の出力は次のとおりです。

([7], [13, 14]) 

私はそれを試してみました:

import collections 
s = [13,12,11,13,14,13,7,11,13,14,12,14,14] 
count = collections.Counter(s) 
mins = [a for a, b in count.items() if b == min(count.values())] 
maxes = [a for a, b in count.items() if b == max(count.values())] 
final_vals = [mins, maxes] 

しかし、私はcollectionsモジュールを使用し、より多くのロジック指向のソリューションを試してみたくありません。
コレクションなしでやるのを手伝ってもらえますか?

+0

「max occure element」(別名_mode_)については、この質問をご覧ください:[リストのモードを探す](https://stackoverflow.com/questions/10797819/finding-the-mode-of -リスト)。 –

+0

[リストのモードを見つける](https://stackoverflow.com/questions/10797819/finding-the-mode-of-a-list) – araknoid

答えて

0
data = [13,12,11,13,14,13,7,11,13,14,12,14,14] 
occurrences = {} 
for i in data: 
    if i in occurrences.keys(): 
      occurrences[i] += 1 
    else: 
      occurrences[i] = 1 

max_vals = [i for i in occurrences.keys() if occurrences[i] == max(occurrences.values())] 
min_vals = [i for i in occurrences.keys() if occurrences[i] == min(occurrences.values())] 
2

あなたはCounterをエミュレートするためdicttryexceptアプローチを使用することができます。

def counter(it): 
    counts = {} 
    for item in it: 
     try: 
      counts[item] += 1 
     except KeyError: 
      counts[item] = 1 
    return counts 

またはalternativlyあなたが0のデフォルトでdict.getを使用することができます。

def counter(it): 
    counts = {} 
    for item in it: 
     counts[item] = counts.get(item, 0) + 1 
    return counts 

そして、あなたはその量を算出繰り返しを避けるために内包外min()max()を行う必要があります(機能は今の代わりにO(n)ですO(n^2)

def minimum_and_maximum_frequency(cnts): 
    min_ = min(cnts.values()) 
    max_ = max(cnts.values()) 
    min_items = [k for k, cnt in cnts.items() if cnt == min_] 
    max_items = [k for k, cnt in cnts.items() if cnt == max_] 
    return min_items, max_items 

その後、予想:collectionsから

defaultdict
>>> minimum_and_maximum_frequency(counter([13,12,11,13,14,13,7,11,13,14,12,14,14])) 
([7], [13, 14]) 
0
s = [13,12,11,13,14,13,7,11,13,14,12,14,14] 

occurrences = dict() 

for item in s: 

    occurrences[item] = occurrences.setdefault(item, 0) + 1 

mins = [a for a, b in occurrences.items() if b == min(occurrences.values())] 
maxs = [a for a, b in occurrences.items() if b == max(occurrences.values())] 

final_vals = [mins, maxs] 

は、リスト内の項目の発生を計算するCounterを交換する方が適しています。しかし、あなたはcollectionsの使用を制限するので。だからsetdefaultKeyErrorを扱う方がよりエレガントです。

0

どのようにこれについて:

s = [13,12,11,13,14,13,7,11,13,14,12,14,14] 
freq_low = s.count(min(s, key=s.count)) 
freq_high = s.count(max(s, key=s.count)) 
mins = [a for a in set(s) if s.count(a) == freq_low] 
maxes = [a for a in set(s) if s.count(a) == freq_high] 
final_vals = [mins, maxes] 
+0

これは 'O(n^4)'ですちょうど 'O(n^3)')ですが、問題は 'O(n)'で簡単に解決できます。 – MSeifert

0

これは非常にシンプルなソリューション、おそらくない最も効率的な1が、シンプルなものです(?)。

data = get_data() 
freqs, numbers = {}, {} 
for i in data: 
    freqs[i] = freqs.get(i, 0) + 1 
for n, c in freqs.items(): 
    numbers[c] = numbers.get(c, []) + [n] 
counts = list(numbers.keys()) 
res = (numbers[min(counts)], numbers[max(counts)]) 

In [1]: data = [13,12,11,13,14,13,7,11,13,14,12,14,14] 

我々は2つの辞書を使用しようとしている、のは あなたが与えた例のデータから始めましょう、我々は上記のスクリプトを持っているものを詳細に見てみましょう

In [2]: freqs, numbers = {}, {} 

最初の数字はdataに反復され、 の個々の数字はdataであり、値はt彼データにおける各 数の周波数(freqs.get(…)ためfotnote参照)

In [3]: for i in data: freqs[i] = freqs.get(i, 0) + 1 

第一方は、単に最初のものの反転であるキーが所定の と周波数と番号のリストである値であります周波数。私たちはすなわち、numbersのキーを使用して、リストを必要とする。この時点で

In [4]: for n, c in freqs.items(): numbers[c] = numbers.get(c, []) + [n] 

In [5]: numbers 
Out[5]: {1: [7], 2: [12, 11], 4: [13, 14]} 

我々は 出現

In [7]: [numbers[min(counts)], numbers[max(counts)]] 
Out[7]: [[7], [13, 14]] 
の最小値と最大値に興味があるので、 は

In [6]: counts = list(numbers.keys()) 

をオカレンス


脚注:.get(key, default_value)辞書のメソッド は、キーが辞書に存在しない場合にデフォルト値を返します。この機能をデフォルト値0で使用して、個々の数字の を合計し、[]のvoidリストを合計して与えられた頻度のすべての数字のリスト

+0

最速のものではないかもしれませんが、すべてのステップ(計数、塊りと極値の発見)は 'O(n)'なので、複雑さはまだ 'O(n)'です... – gboffi

関連する問題