用Python为数据创建直方图

4
我已经在Python中创建了一个函数,用于计算数据的直方图。它有一个参数bins,指定分割的数量。
我以下提供了我的代码,并且数据在链接https://gist.github.com/mesarvagya/11367012上。
import numpy as np
def histogram_using_numpy(filename, bins=10):
    datas =  np.loadtxt(filename, delimiter=" ", usecols=(0,))
    hist,bin_edges = np.histogram(datas, bins)
    return hist
print "from numpy %s" % histogram_using_numpy("ex.txt", bins=10)

def histogram_using_list(filename, bins=10, take_col=0):
    f = open(filename,"r")
    data = []
    for item in f.readlines():
        data.append(float(item.split()[take_col]))
    f.close()
    mi,ma = min(data), max(data)
    bin_length = (ma-mi)/bins
    def get_count(lis,low,diff):
        count = 0
        for item in lis:
            if item >= low and item < low + diff:
                count += 1
        return count
    tot = []    
    for i in np.arange(mi, ma, bin_length):
        tot.append(get_count(data,i, bin_length))
    return tot    
print "From my function %s " % histogram_using_list("ex.txt", bins=10)

现在将两个函数的 bins = 10 的结果比较如下:
from numpy [10 19 20 28 15 16 14 11  5 12]
From my function [10, 19, 20, 28, 16, 15, 14, 11, 5, 12] 

这是错误的。而对于 bins = 15,我得到了以下结果:

from numpy [ 7  4 18 19  5 24  8 10 13  6 13  6  5  1 11]
From my function [7, 4, 18, 19, 10, 19, 8, 10, 13, 10, 9, 6, 5, 1, 11] 

这也是不正确的。假设Numpy是正确的,我的代码有什么问题吗?


为什么你不使用 np.histogram 呢?! - Hadi
不管实际错误是什么,你的方法非常低效。你只需要传递一次数据来获取直方图,而不是每个 bin 都传递一次... - filmor
是的,我只是快速编码,所以没有考虑到那个问题。我关心的是结果:)。我会在我的实际代码中进行更改。谢谢你指出了这一点。 - Mahadeva
1个回答

3
看起来你的代码唯一缺失的是(与前导箱子不同,它们是半开放的)numpy 直方图中的最后一个箱子是闭合的(包括两个端点),而你所有的箱子都是半开放的。(来源,参见“注释”)
如果一个箱子由其边界定义,binminbinmax,那么一个值 x 被分配到该箱子中,如果:
对于前 n-1 个箱子: binmin <= x < binmax 对于最后一个箱子: binmin <= x <= binmax 类似地,np.arange() 也期望一个半开放的区间,所以在接下来的代码中我使用了 np.linspace()
考虑以下内容:
import numpy as np
def histogram_using_numpy(filename, bins=10):
    datas =  np.loadtxt(filename, delimiter=" ", usecols=(0,))
    hist, bin_edges = np.histogram(datas, bins)

    return hist, bin_edges


def histogram_using_list(filename, bins=10, take_col=0):
    f = open(filename,"r")
    data = []
    for item in f.readlines():
        data.append(float(item.split()[take_col]))
    f.close()
    mi,ma = min(data), max(data)

    def get_count(lis,binmin,binmax,inclusive_endpoint=False):
        count = 0
        for item in lis:
            if item >= binmin and item < binmax:
                count += 1
            elif inclusive_endpoint and item == binmax:
                count += 1
        return count

    bin_edges = np.linspace(mi, ma, bins+1)

    tot = []
    binlims = zip(bin_edges[0:-1], bin_edges[1:])
    for i,(binmin,binmax) in enumerate(binlims):
        inclusive = (i == (len(binlims) - 1))
        tot.append(get_count(data, binmin, binmax, inclusive))

    return tot, bin_edges

nump_hist, nump_bin_edges = histogram_using_numpy("ex.txt", bins=15)
func_hist, func_bin_edges = histogram_using_list("ex.txt", bins=15)

print "Histogram:"
print "  From numpy:      %s" % list(nump_hist)
print "  From my function %s" % list(func_hist)
print ""
print "Bin Edges:"
print "  From numpy:      %s" % nump_bin_edges
print "  From my function %s" % func_bin_edges

对于bins=10,输出结果如下:
Histogram:
  From numpy:      [10, 19, 20, 28, 15, 16, 14, 11, 5, 12]
  From my function [10, 19, 20, 28, 15, 16, 14, 11, 5, 12]

Bin Edges:
  From numpy:      [ 4.3   4.66  5.02  5.38  5.74  6.1   6.46  6.82  7.18  7.54  7.9 ]
  From my function [ 4.3   4.66  5.02  5.38  5.74  6.1   6.46  6.82  7.18  7.54  7.9 ]

对于bins=15,输出:

Histogram:
  From numpy:      [7, 4, 18, 19, 5, 24, 8, 10, 13, 6, 13, 6, 5, 1, 11]
  From my function [7, 4, 18, 19, 5, 24, 8, 10, 13, 6, 13, 6, 5, 1, 11]

Bin Edges:
  From numpy:      [ 4.3   4.54  4.78  5.02  5.26  5.5   5.74  5.98  6.22  6.46  6.7   6.94  7.18  7.42  7.66  7.9 ]
  From my function [ 4.3   4.54  4.78  5.02  5.26  5.5   5.74  5.98  6.22  6.46  6.7   6.94  7.18  7.42  7.66  7.9 ]

哦,我明白了。从我的分析来看,我在最后一个索引中得到的结果较低。感谢你指出这一点。 - Mahadeva
@SarvagyaPant 我更新了我的帖子,指出了另一件引起麻烦的事情,就是使用 arrange 而不是 linspace,抱歉一开始忘记了这个。 - jedwards
感谢您的帮助。 :) - Mahadeva
请注意您提供的代码中有一个np.arrange。应该是np.arange。 - Mahadeva

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接