使用动态标准按 id 计数
count by id with dynamic criteria
我有一个 DataFrame,我想向其中添加一个新的列,其中说明每个 ID 和每年有多少次过去有正利润。例如:
id year profit
0 1 2018 0
1 1 2019 10
2 1 2020 20
3 1 2021 0
4 2 2018 0
5 2 2019 20
6 2 2020 10
期望的结果应该是这样的:
id year profit past_profit
0 1 2018 0 0
1 1 2019 10 0
2 1 2020 20 1
3 1 2021 0 2
4 2 2018 0 0
5 2 2019 20 0
6 2 2020 10 1
有什么想法吗?
使用 datar
,一个重新构想 pandas API 的 pandas 包装器,可以很容易地做到这一点:
>>> from datar.all import f, tibble, group_by, mutate, lag, cumsum, as_integer, coalesce
>>>
>>> df = tibble(
... id=[1,1,1,1,2,2,2],
... year=[2018,2019,2020,2021,2018,2019,2020],
... profit=[0,10,20,0,0,20,10]
... )
>>>
>>> (
... df
... >> group_by(f.id)
... >> mutate(
... past_profit=cumsum( # get the cumsum
... as_integer( # convert to integers
... coalesce( # replace NAs with 0
... lag(f.profit > 0), # shift the result
... 0
... )
... )
... )
... )
... )
id year profit past_profit
<int64> <int64> <int64> <int64>
0 1 2018 0 0
1 1 2019 10 0
2 1 2020 20 1
3 1 2021 0 2
4 2 2018 0 0
5 2 2019 20 0
6 2 2020 10 1
[TibbleGrouped: id (n=2)]
我们可以使用 groupby
+ shift
获取过去一年的数据并使用 groupby
+ cumsum
获取每个“id”出现正利润的次数".
df['past_profit'] = (df['profit']>0).groupby(df['id']).shift().fillna(False).groupby(df['id']).cumsum()
输出:
id year profit past_profit
0 1 2018 0 0
1 1 2019 10 0
2 1 2020 20 1
3 1 2021 0 2
4 2 2018 0 0
5 2 2019 20 0
6 2 2020 10 1
请注意,这假设数据按 year
排序。如果没有,我们可以先按 id 和 year 排序;然后使用上面的代码。
df = df.sort_values(by=['id','year'])
我有一个 DataFrame,我想向其中添加一个新的列,其中说明每个 ID 和每年有多少次过去有正利润。例如:
id year profit
0 1 2018 0
1 1 2019 10
2 1 2020 20
3 1 2021 0
4 2 2018 0
5 2 2019 20
6 2 2020 10
期望的结果应该是这样的:
id year profit past_profit
0 1 2018 0 0
1 1 2019 10 0
2 1 2020 20 1
3 1 2021 0 2
4 2 2018 0 0
5 2 2019 20 0
6 2 2020 10 1
有什么想法吗?
使用 datar
,一个重新构想 pandas API 的 pandas 包装器,可以很容易地做到这一点:
>>> from datar.all import f, tibble, group_by, mutate, lag, cumsum, as_integer, coalesce
>>>
>>> df = tibble(
... id=[1,1,1,1,2,2,2],
... year=[2018,2019,2020,2021,2018,2019,2020],
... profit=[0,10,20,0,0,20,10]
... )
>>>
>>> (
... df
... >> group_by(f.id)
... >> mutate(
... past_profit=cumsum( # get the cumsum
... as_integer( # convert to integers
... coalesce( # replace NAs with 0
... lag(f.profit > 0), # shift the result
... 0
... )
... )
... )
... )
... )
id year profit past_profit
<int64> <int64> <int64> <int64>
0 1 2018 0 0
1 1 2019 10 0
2 1 2020 20 1
3 1 2021 0 2
4 2 2018 0 0
5 2 2019 20 0
6 2 2020 10 1
[TibbleGrouped: id (n=2)]
我们可以使用 groupby
+ shift
获取过去一年的数据并使用 groupby
+ cumsum
获取每个“id”出现正利润的次数".
df['past_profit'] = (df['profit']>0).groupby(df['id']).shift().fillna(False).groupby(df['id']).cumsum()
输出:
id year profit past_profit
0 1 2018 0 0
1 1 2019 10 0
2 1 2020 20 1
3 1 2021 0 2
4 2 2018 0 0
5 2 2019 20 0
6 2 2020 10 1
请注意,这假设数据按 year
排序。如果没有,我们可以先按 id 和 year 排序;然后使用上面的代码。
df = df.sort_values(by=['id','year'])