python-3.x - 无需 pandas/numpy 即可对数据进行 Pythonic 方式

标签 python-3.x data-science binning

我正在寻找一种方法,将包含数百个条目的数据集放入 20 个容器中。但不使用 pandas(剪切)和 numpy(数字化)等大模块。 有人能想到比 18 个 elif 更好的解决方案吗?

最佳答案

您需要做的就是找出每个元素位于哪个容器中。考虑到容器的大小(如果它们是统一的),这相当简单。从数组中,您可以找到 minvalmaxval。然后,binwidth = (maxval - minval)/nbins。对于数组 elem 的元素,以及已知的最小值 minval 和 bin 宽度 binwidth,该元素将落入 bin 编号 int((elem - minval)/binwidth)。这就留下了 elem == maxval 的边缘情况。在这种情况下,bin编号等于nbins(nbins +第1个bin,因为python是从零开始的),因此我们必须减少bin编号仅此一例。

因此我们可以编写一个函数来执行此操作:

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)

这给出

[(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 中。

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

关于python-3.x - 无需 pandas/numpy 即可对数据进行 Pythonic 方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64995641/

相关文章:

python的**kwargs效率

python - 如何使用 requirements.txt 或类似的 pickle 对象

plot - 可视化以下数据的最佳方法是什么?

Python:binned_statistic_2d 均值计算忽略数据中的 NaN

python - pandas - 根据另一列中的值使用 bins 定义进行分箱

python - 使用 Flask 中的 JWT 扩展检查 API 响应消息的消息完整性

python - math.log 的错误输出

python-3.x - 使用 Bokeh : How does one plot variable size nodes, 和节点颜色?

python - 为什么我的残差正态 Q-Q 图是一条垂直线?

python - 将所有落在 Pandas 同一时间仓中的行分组