在数据框中使用上个月的信息构建列

Build a column with previous month information in a dataframe

提问人:dsilva 提问时间:11/6/2023 更新时间:11/6/2023 访问量:48

问:

我有这个 df 的例子

我对它进行了一些转换,我需要在新列中获取上个月的标记值以进行比较。该列应根据“id”列中的不同值具有“标记”列的最大值。

下面是 DataFrame 的示例

df = pd.DataFrame({'date':['202301','202301','202301','202301','202302','202302','202302','202302','202303','202303','202303','202304','202304'], 
            'mark': [1,1,2,3,1,1,1,1,1,3,1,1,1
],
                  'id':[20,20,21,21,20,20,21,21,20,20,21,20,21
]})

这是所需的输出

date    mark    id  mark_previous
202301  1   20  0
202301  1   20  0
202301  2   21  0
202301  3   21  0
202302  1   20  1
202302  1   20  1
202302  1   21  3
202302  1   21  3
202303  1   20  1
202303  3   20  1
202303  1   21  1
202304  1   20  3
202304  1   21  1

您建议如何获取该列?

此致敬意!

Python Pandas DataFrame 日期时间

评论


答:

2赞 Gabriel Ramuglia 11/6/2023 #1

您可以通过以下步骤实现所需的内容:

将日期转换为日期时间格式,例如

df['date'] = pd.to_datetime(df['date'], format='%Y%m')

按“id”和“date”对 DataFrame 进行排序

df = df.sort_values(by=['id', 'date'])

按“id”对 DataFrame 进行分组,并使用 groupby 和 shift 函数

df['mark_shifted'] = df.groupby('id')['mark'].shift(1)

创建和使用累积最大值

df['mark_cummax'] = df.groupby(['id', df['date'].dt.to_period('M')])['mark_shifted'].cummax()

清理东西

df['mark_previous'] = df['mark_cummax'].fillna(0).astype(int)
df.drop(columns=['mark_shifted', 'mark_cummax'], inplace=True)

试一试吧!

资料来源:我的文章 https://ioflood.com/blog/pandas-dataframe/

2赞 Panda Kim 11/6/2023 #2

法典

g = df.groupby(['date', 'id'])
df['mark_previous'] = g.tail(1).groupby('id')['mark'].shift()
df['mark_previous'] = g['mark_previous'].transform('max').fillna(0).astype('int')

方向差 :

    date    mark    id  mark_previous
0   202301  1       20  0
1   202301  1       20  0
2   202301  2       21  0
3   202301  3       21  0
4   202302  1       20  1
5   202302  1       20  1
6   202302  1       21  3
7   202302  1       21  3
8   202303  1       20  1
9   202303  3       20  1
10  202303  1       21  1
11  202304  1       20  3
12  202304  1       21  1

中间

g.tail(1).groupby('id')['mark'].shift()

:

1       NaN
3       NaN
5    1.0000
7    3.0000
9    1.0000
10   1.0000
11   3.0000
12   1.0000
Name: mark, dtype: float64