2016-08-04 12 views
0

Ich habe eine Frage zum Rebinning einer Liste von Zahlen, mit einer gewünschten bin-Breite. Es ist im Grunde, was ein Frequenzhistogramm tut, aber ich will nicht das Diagramm, nur die Fachnummer und die Anzahl der Vorkommen für jedes Fach.Rebinning eine Liste von Zahlen in Python

Bis jetzt habe ich bereits Code geschrieben, der tut was ich will, aber es ist nicht sehr effizient. Bei einer Liste a, um es mit einer bin-Breite gleich 3 bis zu REBin habe ich folgendes geschrieben:

import os, sys, math 
import numpy as np 

# list of numbers 
a = list(range(3000)) 

# number of entries 
L = int(len(a)) 

# desired bin width 
W = 3 

# number of bins with width W 
N = int(L/W) 

# definition of new empty array 
a_rebin = np.zeros((N, 2)) 

# cycles to populate the new rebinned array 
for n in range(0,N): 
    k = 0 
    for i in range(0,L): 
     if a[i] >= (W*n) and a[i] < (W+W*n): 
      k = k+1 
    a_rebin[n]=[W*n,k] 

# print 
print a_rebin 

Nun, das ist genau das, was ich will, aber ich denke, es ist nicht so klug ist, wie es liest die ganze Liste N mal, mit N Anzahl der Bins. Es ist in Ordnung für kleine Listen. Aber, da ich mit sehr großen Listen und ziemlich kleinen Behälterbreiten beschäftigen muss, übersetzt sich dies in große Werte von N und der ganze Prozess dauert sehr lange (Stunden ...). Haben Sie Ideen, diesen Code zu verbessern? Vielen Dank im Voraus!

Antwort

1

Wenn Sie a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] verwenden, ist Ihre Lösung:

[[0] 3.
[3. 3.]
[6. 3.]]

Wie interpretierst du das? Die Intervalle sind 0..2, 3..5, 6..8? Ich denke du verpasst etwas.

Mit numpy.histogram()

hist, bin_edges = numpy.histogram(a, bins=int(len(a)/W)) 
print(hist) 
print(bin_edges) 

Ausgang:

[3 3 4]
[0. 3. 6. 9.]

Wir haben 4 Werte in bin_edges: 0, 3, 6 und 9. Alle außer dem letzten (ganz rechts) bin ist halb offen. Das bedeutet, wir haben 3 Intervalle [0,3], [3,6] und [6,9] und wir haben 3, 3 und 4 Elemente in jedem Fach.
Sie können eigene Bins definieren.

import numpy 
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 
bins=[0,1,2] 
hist, bin_edges = numpy.histogram(a, bins=bins) 
print(hist) 
print(bin_edges) 

Ausgang:

[1 2]
[0 1 2]

Jetzt haben Sie 1 Element in [0, 1) und 2 Elemente in [ 1,2].

+0

Mmm ja, mein Algorithmus vermisst die letzte Bin, aber Ihre Lösung führt die letzten zwei Bins zusammen, so scheint es. Für [0,1,2,3,4,5,6,7,8,9] mit einer Binbreite 3 erwarte ich Ereignisse wie [3,3,3,1], aber Sie erhalten [3,3,4 ]. Wenn ich eine Bindung mit 5 wähle, erwarte ich Vorkommnisse als [5,5], aber dieser Code gibt mir Bin-Kanten, die ich nicht verstehe, [0. 4.5 9.] ... Entschuldigung, ich bin nicht sehr an Python gewöhnt ... – urgeo

+0

Wir haben 4 Werte in bin_edges: 0, 3, 6 und 9. Alle außer dem letzten (am weitesten rechts) bin ist halb offen.Das bedeutet, wir haben 3 Intervalle [0,3], [3,6] und [6,9] und wir haben 3, 3 und 4 Elemente in jedem Fach. Sie können eigene Bins definieren: [0,1,2] und jetzt haben Sie 1 Element in [0, 1] und 2 Elemente in [1,2]. OK jetzt? –

0

Numpy hat eine Methode namens np.histogram, die die Arbeit für Sie erledigt. Es skaliert auch ziemlich gut.