【问题标题】:How to create bins in Python如何在 Python 中创建 bin
【发布时间】:2020-11-12 16:54:34
【问题描述】:

我正在尝试在 Python 中创建数据箱,它会产生以下输出。

binsize = 5
data = 0.4, 1.7, 10.7, 8.0, 3.2, 6.7, 11.4, 10.4

(bin_lower_bound - bin_higher_bound)^as a tuple: num_frequency
0.4 - 5.4:  3
5.4 - 10.4: 2
10.4 - 15.4: 3

我尝试使用 for 循环将数据中的较低值用作第一个 bin 的 lower_bound,然后在每个 bin 大小处创建一个新 bin,直到达到最大值。但不幸的是,没有运气。
这个想法是我也在尝试使用字典,但我试图在没有 NUMPY 的情况下实现这一目标。

垃圾箱:{ 0.4 - 5.4:3 5.4 - 10.4:2 10.4 - 15.4:3 }

任何帮助将不胜感激。

【问题讨论】:

  • 是否已经设置了 bin 范围?看起来它们被平均分割为每个 bin 的大小为 5。
  • 跟进@ZWang:你能告诉我们更多关于所需垃圾箱的信息吗?看起来最低的 bin 从 min(data) 开始,大小由binsize 定义。垃圾箱应该相邻吗?例如。如果将值 27 添加到数据中,所需的 bin 是什么?
  • 是的,完全正确。第一个 bin 从最低值开始 - 但我使用用户输入来确定 bin 的大小。

标签: python python-3.x dictionary tuples


【解决方案1】:

下面的方法应该非常有效,并且不使用任何导入(根据要求)。值得注意的是,如果有一个没有任何内容的 bin,则它不会显示在结果中。如果您希望看到没有结果的 bin 为“0”,则必须在 min-max 之间快速循环,然后将所有 bin 设置为 0。现在,它们是根据数据“即时”制作的。

binsize = 5
data = [0.4, 1.7, 10.7, 8.0, 3.2, 6.7, 11.4, 10.4]
min_val = min(data)  # needed to anchor the first bin
bins = {}
for value in data:
    bin_num = int((value - min_val) // binsize) # integer division to find bin
    bins[bin_num] = bins.get(bin_num, 0) + 1

# pretty up the labels...optional
bins2 = { (round(k*binsize+min_val,1), round((k+1)*binsize+min_val,1)) : 
            bins[k] for k in bins }

# or with string-based labels
bins3 = { f'{round(k*binsize+min_val,1)} - {round((k+1)*binsize+min_val,1)}' : 
            bins[k] for k in bins}    

print(bins2)
# {(0.4, 5.4): 3, (2.4, 7.4): 3, (1.4, 6.4): 2}
print(bins3)
# {'0.4 - 5.4': 3, '2.4 - 7.4': 3, '1.4 - 6.4': 2}

【讨论】:

  • 这对@Jeff 非常有帮助 - 我可以看到这对我在本节的代码过程产生了巨大的影响。
【解决方案2】:

这适用于任何数据和任何 binsize。

data = [0.4, 1.7, 10.7, 8.0, 3.2, 6.7, 11.4, 10.4]
data.sort()

from collections import defaultdict
binsize = 5
minval = min(data)
maxval = max(data)

def create_bins(minval, maxval):
    
    bins = []
    
    while minval < maxval:
        bins.append(f"{str(minval)} - {str(minval + binsize)}")
        minval += binsize
        
    return bins
    
bins = create_bins(minval, maxval)

bins_with_values = defaultdict(list)

i = 0
for val in data:
    
    if i < len(bins):
        
        temp = bins[i].split()
        if val < float(temp[2]):
            bins_with_values[bins[i]].append(val)
        else:
            i += 1
            bins_with_values[bins[i]].append(val)
            
print(bins_with_values)

输出

defaultdict(<class 'list'>, {'0.4 - 5.4': [0.4, 1.7, 3.2], '5.4 - 10.4': [6.7, 8.0], '10.4 - 15.4': [10.4, 10.7, 11.4]})

【讨论】:

  • 在上述 cmets 被澄清之后,无论问题是什么,这几乎肯定不是一个好方法。嵌套循环和字符串转换确实不是最佳实践。
  • 与其质疑我的方法,不如给我们一个更好的方法。评论别人的答案总是很容易,然后像你一样离开。
  • 有没有办法在不使用 defaultdict 或为此导入任何内容的情况下做到这一点?
猜你喜欢
  • 2018-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-22
  • 1970-01-01
相关资源
最近更新 更多