首页 > 解决方案 > 有没有办法使用带有阈值的 cumsum 来创建垃圾箱?

问题描述

有没有办法使用 numpy 将系列中的数字添加到阈值,然后重新启动计数器。目的是根据创建的类别形成 groupby。

  amount       price
0   27   22.372505
1   17  126.562276
2   33  101.061767
3   78  152.076373
4   15  103.482099
5   96   41.662766
6  108   98.460743
7  143  126.125865
8   82   87.749286
9   70   56.065133

我发现使用 .loc 进行迭代的唯一解决方案很慢。我尝试根据此答案构建解决方案https://stackoverflow.com/a/56904899

 sumvals = np.frompyfunc(lambda a,b: a+b if a <= 100 else b,2,1)
    df['cumvals'] = sumvals.accumulate(df['amount'], dtype=np.object)

用例是找出每 75 个售出数量的东西的平均价格。

标签: pandas

解决方案


解决方案#1解释以下一种方式将得到我的解决方案:“用例是找到每 75 个售出数量的东西的平均价格。” 如果您尝试以“硬方式”而不是 进行此计算pd.cut,那么这是一个效果很好的解决方案,但速度/内存将取决于列cumsum()amount,如果您这样做,您可以找到df['amount'].cumsum()。每 1000 万个 的输出大约需要 1 秒cumsum,因为这是用 . 创建的行数np.repeat。同样,如果您的 cumsum 少于约 1000 万(1 秒)或什至 1 亿(约 10 秒),则此解决方案并不可怕:

i = 75
df = np.repeat(df['price'], df['amount']).to_frame().reset_index(drop=True)
g = df.index // i
df = df.groupby(g)['price'].mean()
df.index = (df.index * i).astype(str) + '-' + (df.index * i +75).astype(str)
df
Out[1]: 
0-75        78.513748
75-150     150.715984
150-225     61.387540
225-300     67.411182
300-375     98.829611
375-450    126.125865
450-525    122.032363
525-600     87.326831
600-675     56.065133
Name: price, dtype: float64

解决方案#2(我认为这是错误的,但以防万一)我不相信你会这样做,这是我最初的解决方案,但我会把它留在这里以防万一,因为你没有包括预期输出。您可以创建一个新系列,cumsum然后使用pd.cut和传递bins=np.arange(0, df['Group'].max(), 75)创建累积 75 的组。然后,对累积 75 的组进行分组并取平均值。最后,用于pd.IntervalIndex清理格式并更改为字符串:

df['Group'] = df['amount'].cumsum()
s = pd.cut(df['Group'], bins=np.arange(0, df['Group'].max(), 75))
df = df.groupby(s)['price'].mean().reset_index()
df['Group'] = pd.IntervalIndex(df['Group']).left.astype(str) + '-' + pd.IntervalIndex(df['Group']).right.astype(str)
df
Out[1]: 
     Group       price
0     0-75   74.467390
1   75-150  101.061767
2  150-225  127.779236
3  225-300   41.662766
4  300-375   98.460743
5  375-450         NaN
6  450-525  126.125865
7  525-600   87.749286

推荐阅读