大体そうだと思うけど、binningが遅い場合はnumpyで処理すると速くなる。
以下がpandasを使った実装。
def cut_bins(s): m = s.max() categories = pd.cut(s, [0, m * 0.05, m * 0.25, m * 0.75, m * 0.95, m]) category_counts = categories.cat.codes.value_counts() if s.nunique() == 1: return [0, 0, 1, 0, 0] total = category_counts.sum() result = [] for i in range(5): if i in category_counts.index: result.append(str(category_counts[i] / float(total))) else: result.append("0") return ",".join(result) summary_counts = summary.groupby([TITLE])[SALES_COUNT].progress_aggregate(cut_bins)
これをnumpyを使って実装すると以下のようになる。
def cut_bins(s): values = summary[SALES_COUNT].iloc[0:100].values m = values.max() categories = np.digitize(values, [m * 0.05, m * 0.25, m * 0.75, m * 0.95]) unique, counts = np.unique(categories, return_counts=True) d = dict(zip(unique, counts)) total = counts.sum() if total == counts.max(): return "0,0,1,0,0" else: res = [] for i in range(5): if i in d: res.append(str(d[i] / float(total))) else: res.append("0") return ",".join(res) summary_counts = summary.groupby([TITLE])[SALES_COUNT].progress_aggregate(cut_bins)
これで33倍ぐらい速くなった。
参考: