【发布时间】:2019-12-11 22:10:44
【问题描述】:
TLDR:当有>3M 个分类/类别时,如何将pandas.Series 中的记录分配给pd.category?目前正在尝试pd.cut,但这很棘手。
我有一些数据通过直方图运行,然后使用peakutils 找到直方图的峰值。然后我在峰值之间或多或少地拆分数据。我有一个快速的过程来执行此操作,结果看起来或多或少类似于以下内容。
假设我在 bin 位置 [5, 9, 16] 有一个峰值。我想将位于 bin [0, 1, 2, 4, 5, 6, 7] 中的所有数据分配给类 0。 [8, 9, 10, 11, 12] 中的数据到1 类,[13, 14, 15, 16, ...] 中的数据到2 类。
返回的 bin 总数很多 (> 3M)。没关系,因为我的峰值查找速度很快。 问题是,当我尝试使用 pd.cut 将我的 bin 映射回我的原始数据时,事情变得难以处理。
在正常情况下,我的代码如下所示
# data is a pd.Series with about 600k records in it
hist, edges = np.histogram(data, bins='fd')
peakIndex = peakutils.indexes(hist, thres=0.01, min_dist=10)
peaks_counts = np.zeros(len(enges)-1)
# takes forever when length of `edges` >= 3M
bdata = pd.cut(data, bins=edges, include_lowest=True) # <-- This is what needs to be sped up
bdata["codes"] = bdata[data.name].cat.codes
midpoints = peakIndex[:-1\ + np.ceil(np.diff(peakIndex)/2)
midpoints = np.insert(midpoints, 0, 0)
midpoints = np.append(midpoints, len(edges))
# merge the non point bins with the bins that are peaks as described above.
for ix in range(len(midpoints)):
_from = midpoints[ix].astype(int)
_to = midpoints[ix].astype(int)
current_peak = np.arange(_from, _to)
bdata["codes"] = bdata["codes"].replace(current_peak, [edges[ix] for e in current_peak])
直方图hist 的计数有很多0 计数。所以我想我可以很聪明,删除计数为0 的垃圾箱。这样做减少了pd.cut 循环到37k 范围内的垃圾箱总数。它能够在可接受的时间内做到这一点。我认为问题出现在垃圾箱的cat.codes 上。他们不再与我的current_peak 排队。
在我写这篇文章时,我只是想到了一些东西,但必须尝试一下,我仍然会问这个问题,以防比我更聪明的人有更好的想法。也许我可以用edges 或类似的值索引bdata 边缘。
我希望这很清楚..
TIA
【问题讨论】: