python - 从数据框中的今天月份获取月份值 N-(x) 的函数
问题描述
我一直在花费数小时尝试编写一个函数,通过获取今天之前过去 4 个月的数据来检测时间序列中的趋势。我用 dt.month 组织了我的月度数据,但问题是如果今天是 1 月,我无法获得上一年的第 12 个月。这是一个玩具数据集:
data1 = pd.DataFrame({'Id' : ['001','001','001','001','001','001','001','001','001',
'002','002','002','002','002','002','002','002','002',],
'Date': ['2020-01-12', '2019-12-30', '2019-12-01','2019-11-01', '2019-08-04', '2019-08-04', '2019-08-01', '2019-07-20', '2019-06-04',
'2020-01-11', '2019-12-12', '2019-12-01','2019-12-01', '2019-09-10', '2019-08-10', '2019-08-01', '2019-06-20', '2019-06-01'],
'Quantity' :[3,5,6,72,1,5,6,3,9,3,6,7,3,2,5,74,3,4]
})
我的数据清理以获得我需要的格式是这样的:
data1['Date'] =pd.to_datetime(data1['Date'], format='%Y-%m')
data2 = data1.groupby('Id').apply(lambda x: x.set_index('Date').resample('M').sum())['Quantity'].reset_index()
data2['M'] =pd.to_datetime(data2['Date']).dt.month
data2['Y'] =pd.to_datetime(data2['Date']).dt.year
data = pd.DataFrame(data2.groupby(['Id','Date','M','Y'])['Quantity'].sum())
data = data.rename(columns={0 : 'Quantity'})
我的功能如下所示:
def check_trend():
today_month = int(time.strftime("%-m"))
data['n3-n4'] = data['Quantity'].loc[data['M']== (today_month - 3)]-data['Quantity'].loc[data['M']== (today_month - 4)]
data['n2-n3'] = data['Quantity'].loc[data['M'] == (today_month - 2)] - data['Quantity'].loc[data['M'] == (today_month - 3)]
data['n2-n1'] = data['Quantity'].loc[data['M'] == (today_month - 2)] - data['Quantity'].loc[data['M'] == (today_month - 1)]
if data['n3-n4'] < 0 and data['n2-n3'] <0 and data['n2-n1'] <0:
elif data['n3-n4'] > 0 and data['n2-n3'] > 0 and dat['n2-n1'] >0:
data['Trend'] = 'Yes'
else:
data['Trend'] = 'No'
print(check_trend)
我看过这个:Get (year,month) for the last X months但它似乎不适用于特定的 groupby 对象。
我真的很感激一个提示!至少我很想知道这种识别数据集中趋势的方法是否很好。之后,如果没有趋势,我计划使用指数平滑,如果有趋势,我计划使用 Holt 方法。
更新:感谢@Vorsprung durch Technik,我的功能运行良好,但我仍然难以将结果合并到包含来自 data2 的 Id 的新数据框中
forecast = pd.DataFrame()
forecast['Id'] = data1['Id'].unique()
for k,g in data2.groupby(level='Id'):
forecast['trendup'] = g.tail(5)['Quantity'].is_monotonic_increasing
forecast['trendown'] = g.tail(5)['Quantity'].is_monotonic_decreasing
这将为数据集的每一行返回相同的值,就像它只计算第一行一样,我如何确保它为每个 Id 值计算?
解决方案
我认为你不需要check_trend()
。
为此有内置函数:
https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Index.is_monotonic_increasing.html
https://pandas.pydata.org/pandas-docs/稳定/参考/api/pandas.Index.is_monotonic_decreating.html
让我知道这是否满足您的需要:
data2 = data1.groupby('Id').apply(lambda x: x.set_index('Date').resample('M').sum())
for k,g in data2.groupby(level='Id'):
print(g.tail(4)['Quantity'].is_monotonic_increasing)
print(g.tail(4)['Quantity'].is_monotonic_decreasing)
这是返回的内容g.tail(4)
:
Quantity
Id Date
001 2019-10-31 0
2019-11-30 72
2019-12-31 11
2020-01-31 3
Quantity
Id Date
002 2019-10-31 0
2019-11-30 0
2019-12-31 16
2020-01-31 3
推荐阅读
- ios - 反应原生 forceRTL false 在 iOS 上不起作用
- nestjs - 使用 NVM 设置 NestJS 项目时出现 EBADENGINE 警告
- mysql - SQL计算具有行值的不同列
- flutter - 错误:不能将“String”类型的值分配给“int”类型的变量
- perl - 停止使用 DB::DB 创建的探查器以再次显示未真正调用的调用
- android - Android Compose MVVM 多网络调用
- json - 如何在列表中显示列的所有文本?
- arrays - 我在 malloc 哪里做错了?
- git - 相当于 p4 sync -n 的 git 命令
- c# - 如何使用 Graph Api 替换 Onedrive 中的文件?