【问题标题】:Aggregating over random subsets of n rows of dataframe in python在python中聚合n行数据帧的随机子集
【发布时间】:2020-03-31 05:52:11
【问题描述】:

我正在尝试聚合具有 n 行的 python 数据帧的随机子集。我目前的方法是遍历行并在新列中分配一个“组 id”,然后在该列上聚合,但是我的数据框有数十万行,这太慢了。有什么更有效的方法来做到这一点?

rand = np.random.RandomState(1)
df = pd.DataFrame({'column1': rand.randn(300000), 'column2': rand.rand(300000)})
df['groupid'] = 0
df = df.sample(frac=1).reset_index(drop=True) #randomize dataframe rows
group_size = [1, 10, 100, 1000, 10000]
for size in group_size:
        group_num = 0
        for position in range(0, len(df), size):
            df.iloc[position:position + size, df.columns.get_loc('groupid')] =  group_num
            group_num+=1

        results = df.groupby(['groupid'], as_index=True).agg({'column1': 'mean', 'column2': 'mean'})

编辑:我需要准确地使用每一行数据一次。输出应该是一个数据框,每一行给出每个组的 column1 和 column2 的平均值(例如results.shape[0] = np.ceil(df.shape[0]/size)

更新: 我能够通过首先随机化数据框然后使用 itertools 生成具有重复序列号的列表来快速实现所需的行为:

rand = np.random.RandomState(1)
df = pd.DataFrame({'column1': rand.randn(300000), 'column2': rand.rand(300000)})
df = df.sample(frac=1).reset_index(drop=True) #randomize dataframe rows
group_size = [1, 10, 100, 1000, 10000]
for size in group_size:
        df['groupid'] = list(itertools.chain.from_iterable(itertools.repeat(x, size) for x in range(int(np.ceil(df.shape[0]/size)))))[0:df.shape[0]]
        results = df.groupby(['groupid'], as_index=True).agg({'column1': 'mean', 'column2': 'mean'})

【问题讨论】:

  • 您能否分享一个包含样本数据和预期输出的可重现示例?

标签: python pandas dataframe


【解决方案1】:

您可以使用np.random.shuffle 函数随机打乱数组:

n = df.shape[0]
for gs in group_size:

    a = np.hstack([np.repeat(np.arange(gs), n//gs), np.arange(n%gs)]) 
    np.random.shuffle(a)

    df[f'group_size_{gs}'] = a

注意np.random.shuffle 就地修改数组。

【讨论】:

  • 这似乎不能保证组的大小相等。
  • @Kyle 你是对的,这是一个快速的捷径。我现在编辑了我的答案。
【解决方案2】:

Pandas 内置了采样方法。

df = df.sample(n=10)

这将返回一个由 10 个随机采样的 df 行组成的数据帧。无需 groupby,只需在此上聚合即可。

【讨论】:

  • 根据我的编辑,我需要准确地使用每一行一次,所以我不相信这会起作用。
猜你喜欢
  • 2022-05-21
  • 1970-01-01
  • 2016-10-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-04
  • 2018-06-19
  • 2020-02-05
相关资源
最近更新 更多