在Python中将一个种群分成两个

在Python中将一个种群分成两个,python,numpy,statistics,Python,Numpy,Statistics,我有一个值列表,描述了一些总体。这些值分布为两个峰值,如下面的直方图所示。 是否有一种简单的方法可以自动检测分布中心的“间隙”,并将初始列表分成两边?如果可能,最好使用numpy 编辑添加:显然,我可以对列表进行排序、迭代并在第一个零值处拆分,但我希望有一种更稳健的方法,它“合理”,即使两个峰值没有如此清晰地分开。请注意,删除注释不起作用,是直方图有零值,而不是数据,哎呀 如果您有关于您的分布的先验信息,例如:正好有两组样本在组内连续。然后,您可以使用一个简单的算法:找到两个样本之间的较大差距

我有一个值列表,描述了一些总体。这些值分布为两个峰值,如下面的直方图所示。

是否有一种简单的方法可以自动检测分布中心的“间隙”,并将初始列表分成两边?如果可能,最好使用numpy


编辑添加:显然,我可以对列表进行排序、迭代并在第一个零值处拆分,但我希望有一种更稳健的方法,它“合理”,即使两个峰值没有如此清晰地分开。请注意,删除注释不起作用,是直方图有零值,而不是数据,哎呀

如果您有关于您的分布的先验信息,例如:正好有两组样本在组内连续。然后,您可以使用一个简单的算法:找到两个样本之间的较大差距


但是将一个群体划分为子集(簇)的问题并不简单,通常通过机器学习聚类算法来解决:

Jean loup的答案对于所提出的问题非常有效。然而,有一个工作,简单的实现让我能够思考问题多一点,我张贴的方法,我想出了太多的情况下,它是有用的

def split_population2(seq, n_bins):
    """ Split a population into sub-populations

        Based on binning the data into n_bins and finding contigous groups of non-empty bins.

        Returns [lowest, ..., highest] all of which are sorted sequences
    """
    sorted_pop = sorted(seq)

    # bin the data into n_bins in a 2d structure, one sequence for each bin:
    _ , bins = np.histogram(sorted_pop, bins=n_bins)
    bin_indices = np.digitize(sorted_pop, bins)
    binned = []
    for i in range(len(bins)+1):
        binned.append([])
    for ix_bin, v in zip(bin_indices, sorted_pop):
        binned[ix_bin].append(v)

    # now join-up non-empty bins
    joined_bins = [[]] # so 2D, with initially 1 sub-list
    len_last_bin = 0
    for bin in binned:
        len_bin = len(bin)
        if len_bin == 0 and len_last_bin != 0: # will correctly handle the case where bin 0 is empty
            joined_bins.append([])
        if len_bin != 0:
            joined_bins[-1].extend(bin)
        len_last_bin = len_bin

    return joined_bins
我认为这将适用于有2个以上子种群的情况,并且对于子种群明显分离的情况应该相对稳健。缺点是,在某些情况下,答案将取决于为
n\u bins
选择的值


只有一次拆分?如果还有一个样本呢?例如:在0.4Well,只有2个子群体是最初假设的一部分,但你让我对我的特殊情况提出了质疑!谢谢我将接受这一点,因为它确实回答了最初的问题,但提出了一种更灵活的方法作为补充答案。