2009-11-12 39 views
8

J'ai un ensemble de valeurs dans float (toujours inférieur à 0). Ce que je veux bin dans l'histogramme, je, e. chaque barre histogramme contient plage de valeurs [0,0.150)Comment archiver des séries de valeurs flottantes dans l'histogramme en Python?

Les données que j'ai ressemble à ceci:

0.000 
0.005 
0.124 
0.000 
0.004 
0.000 
0.111 
0.112 

Whith mon code ci-dessous je me attends à obtenir un résultat qui ressemble à

[0, 0.005) 5 
[0.005, 0.011) 0 
...etc.. 

J'ai essayé de faire un tel binning avec ce code à moi. Mais cela ne semble pas fonctionner. Quelle est la bonne façon de le faire?

#! /usr/bin/env python 


import fileinput, math 

log2 = math.log(2) 

def getBin(x): 
    return int(math.log(x+1)/log2) 

diffCounts = [0] * 5 

for line in fileinput.input(): 
    words = line.split() 
    diff = float(words[0]) * 1000; 

    diffCounts[ str(getBin(diff)) ] += 1 

maxdiff = [i for i, c in enumerate(diffCounts) if c > 0][-1] 
print maxdiff 
maxBin = max(maxdiff) 


for i in range(maxBin+1): 
    lo = 2**i - 1 
    hi = 2**(i+1) - 1 
    binStr = '[' + str(lo) + ',' + str(hi) + ')' 
    print binStr + '\t' + '\t'.join(map(str, (diffCounts[i]))) 

~

+0

Eh bien, dans l'exemple « ce que vous attendez ... », si vous avez des plages définies comme [0, 0,005) (droit ouvert) et [0,005, 0,011) (fermé à gauche) puis la sortie doit être: [0, 0.005) 4 [0.005, 0.011) 1 etc ... – Gacek

+0

"Ne semble pas fonctionner?" Une plainte spécifique? Ou pensez-vous que tout le monde doit l'exécuter et essayer de deviner ce que vous n'aimez pas dans la sortie? –

+0

Pour éviter de réinventer la roue, en particulier si l'étape suivante consiste à tracer votre histogramme: vous devriez envisager d'utiliser le framework Matplotlib qui gère tout cela. – RedGlyph

Répondre

13

Si possible, ne pas réinventer la roue. NumPy a tout ce dont vous avez besoin:

#!/usr/bin/env python 
import numpy as np 

a = np.fromfile(open('file', 'r'), sep='\n') 
# [ 0.  0.005 0.124 0.  0.004 0.  0.111 0.112] 

# You can set arbitrary bin edges: 
bins = [0, 0.150] 
hist, bin_edges = np.histogram(a, bins=bins) 
# hist: [8] 
# bin_edges: [ 0. 0.15] 

# Or, if bin is an integer, you can set the number of bins: 
bins = 4 
hist, bin_edges = np.histogram(a, bins=bins) 
# hist: [5 0 0 3] 
# bin_edges: [ 0.  0.031 0.062 0.093 0.124] 
+0

Et si vous voulez un histogramme normalisé, vous pouvez ajouter la ligne: hist = hist * 1.0/sum (hist) – dval

+0

Et si vous voulez que l'intégrale sur la plage bin soit de 1, utilisez ['density = True'] (http://docs.scipy.org/doc/numpy-1.10.1/reference/ généré/numpy.histogram.html). – unutbu

2

La première erreur est:

Traceback (most recent call last): 
    File "C:\foo\foo.py", line 17, in <module> 
    diffCounts[ str(getBin(diff)) ] += 1 
TypeError: list indices must be integers 

Pourquoi vous int la conversion d'un à un str lorsqu'une str est nécessaire? Corrigez cela, puis nous obtenons:

Traceback (most recent call last): 
    File "C:\foo\foo.py", line 17, in <module> 
    diffCounts[ getBin(diff) ] += 1 
IndexError: list index out of range 

parce que vous avez seulement fait 5 seaux. Je ne comprends pas votre système de héliporté, mais nous allons faire ce 50 seaux et voir ce qui se passe:

6 
Traceback (most recent call last): 
    File "C:\foo\foo.py", line 21, in <module> 
    maxBin = max(maxdiff) 
TypeError: 'int' object is not iterable 

maxdiff est une valeur unique de votre liste de ints, donc ce qui est max ici? Retirez-le, maintenant, nous obtenons:

6 
Traceback (most recent call last): 
    File "C:\foo\foo.py", line 28, in <module> 
    print binStr + '\t' + '\t'.join(map(str, (diffCounts[i]))) 
TypeError: argument 2 to map() must support iteration 

Effectivement, vous utilisez une seule valeur comme second argument à map. Simplifions les deux dernières lignes de cette:

binStr = '[' + str(lo) + ',' + str(hi) + ')' 
print binStr + '\t' + '\t'.join(map(str, (diffCounts[i]))) 

à cette:

print "[%f, %f)\t%r" % (lo, hi, diffCounts[i]) 

Maintenant, il imprime:

6 
[0.000000, 1.000000) 3 
[1.000000, 3.000000) 0 
[3.000000, 7.000000) 2 
[7.000000, 15.000000) 0 
[15.000000, 31.000000) 0 
[31.000000, 63.000000) 0 
[63.000000, 127.000000) 3 

Je ne sais pas quoi faire d'autre ici, puisque je ne comprends pas vraiment le seau que vous espérez utiliser. Il semble impliquer des pouvoirs binaires, mais n'a pas de sens pour moi ...

3
from pylab import * 
data = [] 
inf = open('pulse_data.txt') 
for line in inf: 
    data.append(float(line)) 
inf.close() 
#binning 
B = 50 
minv = min(data) 
maxv = max(data) 
bincounts = [] 
for i in range(B+1): 
    bincounts.append(0) 
for d in data: 
    b = int((d - minv)/(maxv - minv) * B) 
    bincounts[b] += 1 
# plot histogram 

plot(bincounts,'o') 
show()