【问题标题】:Downsample pandas data frame based on count column基于计数列对熊猫数据框进行下采样
【发布时间】:2018-12-18 22:01:18
【问题描述】:

我有数千个如下所示的数据框,但要大得多(1000000 行,100 列)。

data = pd.DataFrame({'cols1':[4, 5, 5, 4, 321, 32, 5],
                     'count':[45, 66, 6, 6, 1, 432, 3],
                     'Value':['Apple', 'Boy', 'Car', 'Corn', 'Anne', 'Barnes', 'Bayesian']})

我想从这个数据帧中随机抽样并制作一个新的数据帧,这样计数的总和应该只等于 N。这意味着我想根据计数值作为权重随机抽样,并制作一个新的数据帧使用这个新的重采样数据,使得计数总和为 N。

相对比例应保持大致相同,重采样时的值不应超过原始计数值的计数。 cols1(或除 Value 和 count 之外的任何其他列)中的值应保持不变。

例如,如果 N 是 50,它可能看起来像:

pd.DataFrame({'cols1':[4, 5, 5, 4, 321, 32, 5],
                     'count':[4, 7, 1, 1, 0, 37, 0],
                     'Value':['Apple', 'Boy', 'Car', 'Corn', 'Anne', 'Barnes', 'Bayesian']})

如何做到这一点?

效率是关键,否则我可以根据计数扩展数据框并随机抽样而不进行替换,然后将其重新合并在一起。

谢谢, 杰克

【问题讨论】:

  • 此操作的结果不会改变数据框的形状。为什么不做np.ceil(df.count * N / df.count.sum())。生成的count 列保持相同的频率分布,但其总和可能会相差一个小整数,然后您可以从行中随机添加/减去等于N
  • 我喜欢这个想法,但我不想无意中添加可能会扭曲下游结果的偏差。因此,我想在不替换的情况下进行随机抽样,但是计数列指定了一个值可以被抽样的最大次数,而不将其称为使用替换。

标签: python pandas


【解决方案1】:

使用多项式采样,这相对容易。

import numpy as np
from itertools import chain

def downsample(df, N):
    prob = df['count']/sum(df['count'])
    df['count'] = list(chain.from_iterable(np.random.multinomial(n = N, pvals = prob, size = 1)))
    df = df[df['count'] != 0]
    return df

以 OP 为例:

downsample(data, 50)

返回:

    Value  cols1  count
1     Boy      5      1
3    Corn      4     16
5  Barnes     32     33

【讨论】:

    猜你喜欢
    • 2020-11-18
    • 2017-05-28
    • 2020-12-30
    • 1970-01-01
    • 1970-01-01
    • 2021-09-07
    • 1970-01-01
    • 2016-03-19
    • 2021-12-23
    相关资源
    最近更新 更多