0

私はThink Pythonに取り組んでおり、次のことを行う関数を作成する演習があります。

  • 引数として取る: L(数値のリスト) およびn(および int)
  • nサブ リストのリストの形でヒストグラムを返す
    • 各サブリストは、 の数値でカバーされる範囲の下位区分を表し、その下位区分に該当Lする の要素の数を表す int を含みますL

したがって、数値の範囲を見て、その範囲をn等しいバケットに切り刻み、それらのバケットを使用してヒストグラムを作成します。この演習の前のセクションでは、区間 [0.0, 1.0) 内のランダムな float のリストを処理するときに、そのような関数を構築する方法を示しています。要素がその間隔 (単にその値) のどこにあるかを調べ、それを で乗算しn、int に変換します (プロセスで切り捨てられます)。これにより、適切なバケット インデックスである [0, n) の int が生成されます。

ここでの違いは、あらかじめ決められた (そして便利な) 間隔で作業していないことです。これが私が思いついたものです。これを行うためのよりエレガントな方法があるかどうか知りたいです。間隔を として計算しmax(L) - min(L)ましたが、それに少し余分に追加する必要がありました。そうしないと、 の最大要素Lが n (範囲外) のインデックスを取得しますが、代わりに n - 1 を取得する必要がありますextraBit

def histogram(L, n):
    hist = [0] * numBuckets
    minVal = min(L)
    maxVal = max(L)
    extraBit = .0000000000001
    interval = (maxVal - minVal) + extraBit

    for i in L:
        placement = (i - minVal) / interval
        index = int(placement * numBuckets)
        hist[index] = hist[index] + 1

    return hist

これを行うためのよりきれいな方法はありますか?

4

1 に答える 1

2

私は先週自分で書いた:

def frequency_count(itt, nr_bins, minn=None, maxx=None):
    ret = []
    if minn == None:
        minn = min(itt)
    if maxx == None:
        maxx = max(itt)
    binsize = (maxx - minn) / float(nr_bins) #man, do I hate int division

    #construct bins
    ret.append([float("-infinity"), minn, 0]) #-inf -> min
    for x in range(0, nr_bins):
        start = minn + x * binsize
        ret.append([start, start+binsize, 0])
    ret.append([maxx, float("infinity"), 0]) #maxx -> inf

    #assign items to bin
    for item in itt:
        for binn in ret:
            if binn[0] <= item < binn[1]:
                binn[2] += 1        
    return ret 

これにより、範囲全体ではなく、値のスライスを取得できます。-inf->minおよびmax->infキャッチオールバケットを追加することで、オーバーフローの問題を修正します。これがあなたに受け入れられるかどうかはわかりません。

于 2013-02-05T16:59:22.840 に答える