【问题标题】:Pandas: Increment or reset count based on another columnPandas:根据另一列增加或重置计数
【发布时间】:2023-03-27 00:20:01
【问题描述】:

我有一个代表分数时间序列的 Pandas DataFrame。我想使用该分数根据以下标准计算 CookiePoints 列:

  • 与之前的分数相比,每次分数提高时,都会给出一个 CookiePoint。
  • 每次分数没有提高,所有的CookiePoints都会被拿走作为惩罚(CookiePoints设置为0)。
  • 3 Cookiepoints 可以换成 Cookie。因此,达到 3 后,CookiePoints 计数应为 1(如果得分较高)或 0(如果得分不较高)。

示例如下:

Score       CookiePoints
14          0
13          0
14          1
17          2
17          0
19          1
20          2
22          3
23          1
17          0
19          1
20          2
22          3
21          0

请注意,这是minimal, reproducible example。解决方案必须使用 Pandas DataFrame,并且最好只使用矢量化操作。

【问题讨论】:

标签: python pandas


【解决方案1】:

这当然是一个棘手的问题,但仍然可以在 Pandas 中解决。 (更新V3解决方案)

第 3 版(OneLiner)

score = pd.Series([14,13,14,17,17,19,20,22,23,17,19,20,22,21])
result = score.diff().gt(0).pipe(lambda x:x.groupby((~x).cumsum()).cumsum().mod(3).replace(0,3).where(x,0).map(int))

第 2 版

score = pd.Series([14,13,14,17,17,19,20,22,23,17,19,20,22,21])

mask= score.diff()>0        

result = mask.groupby((~mask).cumsum()).cumsum().mod(3).replace(0,3).where(mask,0).map(int)

版本 1

score = pd.Series([14,13,14,17,17,19,20,22,23,17,19,20,22,21])

mask= score.diff()>0        # Identify score going up

mask 

0     False
1     False
2      True
3      True
4     False
5      True
6      True
7      True
8      True
9     False
10     True
11     True
12     True
13    False
dtype: bool

# Use False Cumsum to group True values

group = (mask==False).cumsum()

group
0     1
1     2
2     2
3     2
4     3
5     3
6     3
7     3
8     3
9     4
10    4
11    4
12    4
13    5
dtype: int64

# Groupby False Cumsum
temp = mask.groupby(group).cumsum().map(int)
temp

0     0
1     0
2     1
3     2
4     0
5     1
6     2
7     3
8     4
9     0
10    1
11    2
12    3
13    0
dtype: int64

# Fix Cap at 3
# result = temp.where(temp<=3,temp.mod(3)) # This is Wrong. 

result = temp.mod(3).replace(0,3).where(mask,0)
result

0     0
1     0
2     1
3     2
4     0
5     1
6     2
7     3
8     1
9     0
10    1
11    2
12    3
13    0
dtype: int64

【讨论】:

  • 最后一行有一个小问题。我会尽快修复它。 (固定)
  • 很好的答案,我尝试了一段时间来制作一个衬里,但我没有成功。模组的使用非常巧妙。
  • 不是很易读但很聪明,如果我以后遇到类似的问题会访问这个帖子
  • @Datanovice 好吧..这是一个班轮的成本:)
  • 谢谢你,这非常有帮助,也非常令人印象深刻。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-18
  • 1970-01-01
  • 2021-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多