【发布时间】:2021-07-13 10:29:47
【问题描述】:
我遇到了一个问题,即必须跨多个内核处理数据。让 df 成为 Pandas DataFrameGroupBy (size()) 对象。每个值代表每个 GroupBy 对核心的计算“成本”。如何将 df 划分为 大小不等 且计算成本相同 (近似)的 n 箱?
import pandas as pd
import numpy as np
size = 50
rng = np.random.default_rng(2021)
df = pd.DataFrame({
"one": np.linspace(0, 10, size, dtype=np.uint8),
"two": np.linspace(0, 5, size, dtype=np.uint8),
"data": rng.integers(0, 100, size)
})
groups = df.groupby(["one", "two"]).sum()
df
one two data
0 0 0 75
1 0 0 75
2 0 0 49
3 0 0 94
4 0 0 66
...
45 9 4 12
46 9 4 97
47 9 4 12
48 9 4 32
49 10 5 45
人们通常将数据集拆分为 n 个箱,例如下面的代码。但是,将数据集分成 n 等份是不可取的,因为核心接收非常不平衡的工作负载,例如205 与 788。
n = 4
bins = np.array_split(groups, n) # undesired
[b.sum() for b in bins] #undesired
[data 788
dtype: int64, data 558
dtype: int64, data 768
dtype: int64, data 205
dtype: int64]
理想的解决方案是将数据拆分为大小不等且总和值大致相等的 bin。 IE。 abs(743-548) = 195 之间的差异小于之前的方法abs(205-788) = 583。差异应尽可能小。一个简单的列表示例,说明它应该如何实现:
# only an example to demonstrate desired functionality
example = [[[10, 5], 45], [[2, 1], 187], [[3, 1], 249], [[6, 3], 262]], [[[9, 4], 153], [[4, 2], 248], [[1, 0], 264]], [[[8, 4], 245], [[7, 3], 326]], [[[5, 2], 189], [[0, 0], 359]]
[sum([size for (group, size) in test]) for test in t] # [743, 665, 571, 548]
在 pandas 或 numpy 中是否有更有效的方法将数据集拆分为 bin?
拆分/装箱 GroupBy 对象很重要,以与np.array_split() 返回的类似方式访问数据。
【问题讨论】:
标签: python pandas numpy multiprocessing bins