首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Pythonic式的数据入库方式,无需pandas/numpy

Pythonic式的数据入库方式,无需pandas/numpy
EN

Stack Overflow用户
提问于 2020-11-25 06:15:21
回答 1查看 353关注 0票数 1

我正在寻找一种方法来将数百个条目的数据集放入20个箱中。但没有使用像pandas (cut)和numpy (数字化)这样的大模块。有谁能想到比18个elifs更好的解决方案吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-11-25 06:31:03

您所要做的就是找出每个元素所在的bin。考虑到垃圾箱的大小,如果它们是均匀的,这是相当微不足道的。从您的数组中,您可以找到minvalmaxval。然后是binwidth = (maxval - minval) / nbins。对于数组elem的一个元素,以及一个已知的最小值minval和bin宽度binwidth,该元素将落在bin编号int((elem - minval) / binwidth)中。这就留下了边缘情况,其中elem == maxval。在本例中,bin号等于nbins (nbins + 1的th个bin,因为python是从零开始的),所以我们必须减少这一种情况下的bin号。

所以我们可以写一个函数来做这件事:

代码语言:javascript
运行
复制
import random

def splitIntoBins(arr, nbins, minval=None, maxval=None):
    minval = min(arr) if minval is None else minval # Select minval if specified, otherwise min of data
    maxval = max(arr) if maxval is None else maxval # Same for maxval
    
    binwidth = (maxval - minval) / nbins # Bin width
    allbins = [[] for _ in range(nbins)] # Pre-make a list-of-lists to hold values

    for elem in arr:
        binnum = int((elem - minval) // binwidth) # Find which bin this element belongs in
        binindex = min(nbins-1, binnum) # To handle the case of elem == maxval
        allbins[binindex].append(elem) # Add this element to the bin
    return allbins

# Make 1000 random numbers between 0 and 1
x = [random.random() for _ in range(1000)]

# split into 10 bins from 0 to 1, i.e. a bin every 0.1
b = splitIntoBins(x, 10, 0, 1)

# Get min, max, count for each bin
counts = [(min(v), max(v), len(v)) for v in b]
print(counts)

这给了我们

代码语言:javascript
运行
复制
[(0.00017731201786974626, 0.09983758434153, 101),
 (0.10111204267013452, 0.19959594179848794, 97),
 (0.20089309189822557, 0.2990120768922335, 100),
 (0.3013915797055913, 0.39922131591077614, 90),
 (0.4009006835799309, 0.49969892298935836, 83),
 (0.501675740585966, 0.5999729295882031, 119),
 (0.6010149249108184, 0.7000366124696699, 120),
 (0.7008002068562794, 0.7970568220766774, 91),
 (0.8018697850229161, 0.8990963218226316, 99),
 (0.9000732426223624, 0.9967964437788829, 100)]

这看起来就是我们所期望的。

对于非均匀仓位,它不再是算术计算。在这种情况下,元素elem位于下界小于elem,上界大于elem的bin中。

代码语言:javascript
运行
复制
def splitIntoBins2(arr, bins):
    binends = bins[1:]
    binstarts = bins[:-1]
    allbins = [[] for _ in binends] # Pre-make a list-of-lists to hold values

    for elem in arr:
        for i, (lower_bound, upper_bound) in enumerate(zip(binstarts, binends)):
            if upper_bound >= elem and lower_bound <= elem:
                allbins[i].append(elem) # Add this element to the bin
                break
    return allbins
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64995641

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档