在Python中将一个种群分成两个
我有一个值列表,描述了一些总体。这些值分布为两个峰值,如下面的直方图所示。 是否有一种简单的方法可以自动检测分布中心的“间隙”,并将初始列表分成两边?如果可能,最好使用numpy在Python中将一个种群分成两个,python,numpy,statistics,Python,Numpy,Statistics,我有一个值列表,描述了一些总体。这些值分布为两个峰值,如下面的直方图所示。 是否有一种简单的方法可以自动检测分布中心的“间隙”,并将初始列表分成两边?如果可能,最好使用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个子群体是最初假设的一部分,但你让我对我的特殊情况提出了质疑!谢谢我将接受这一点,因为它确实回答了最初的问题,但提出了一种更灵活的方法作为补充答案。