python - 识别熊猫系列中多个连续值为负数的时期
问题描述
给定一个以年份为索引的 pandas 系列(按升序排列,没有缺失年份):
growth = pd.Series({1990: 6.99, 1991: 5.53, 1992: -9.02, 1993: 1.05, 1994: 9.24, 1995: 0.16, 1996: 10.36, 1997: 2.68, 1998: 2.89, 1999: -0.82, 2000: -3.06, 2001: 1.44, 2002: -8.89, 2003: -17.0, 2004: -5.81, 2005: -5.71, 2006: -3.46, 2007: -3.65, 2008: -17.67, 2009: 12.02, 2010: 19.68, 2011: 14.19, 2012: 16.67, 2013: 1.99, 2014: 2.38, 2015: 1.78, 2016: 0.76, 2017: 4.7, 2018: 3.5, 2019: -8.1, 2020: -8.0})
growth
我需要确定至少min_duration
连续几年为负数的时期(开始年和结束年) 。
我可以通过遍历系列来做到这一点:
def get_negative_periods(s, min_duration):
previous = 1
negative_periods = []
for year, value in s.items():
if value < 0:
if previous < 0:
negative_periods[-1].append(year)
else:
negative_periods.append([year])
previous = value
return [(period[0], period[-1]) for period in negative_periods
if len(period) >= min_duration]
例如get_negative_periods(growth, 3)
回报[(2002, 2008)]
,因为 2002-2008 年是唯一growth
连续 3 年或更长时间为负数的时期。
有没有办法将它矢量化而不是逐行进行?(返回一个系列或数据框而不是元组就可以了。)
解决方案
尝试根据位置True
和False
不同创建组,然后仅保留年份范围大于或等于的 True 组min_duration
:
def get_negative_periods(s, min_duration):
s = s.lt(0).reset_index()
g = s[0].ne(s[0].shift()).cumsum()[s[0].eq(True)]
s = s.groupby(g)['index'].agg(['first', 'last'])
return s[(s['last'] - s['first']) + 1 >= min_duration]
res = get_negative_periods(growth, 3)
res
:
first last
0
6.0 2002 2008
或作为列表列表:
def get_negative_periods(s, min_duration):
s = s.lt(0).reset_index()
g = s[0].ne(s[0].shift()).cumsum()[s[0].eq(True)]
s = s.groupby(g)['index'].agg(['first', 'last'])
return s[(s['last'] - s['first']) + 1 >= min_duration].values.tolist()
lst = get_negative_periods(growth, 3)
lst
:
[[2002, 2008]]
推荐阅读
- java - Java 小程序不显示 FXML 形式
- websocket - Websocket 设计 - 多条路由(许多连接)或处理所有事情的单个路由?
- c# - 如何使用 FluentAssertions 控制字典成员的“平等”
- c# - 单一责任原则和 LINQ to Entity
- javascript - 如何在 javascript 中使用 CryptoJS
- php - PHP - 强制 eval() 在全局范围内运行
- javascript - 节点js需要执行功能
- android - 如何忽略触摸事件,让安卓系统处理?
- android - BottomAppBar 忽略“layout_gravity”,始终显示在顶部
- python - 允许来自我的 zappa 应用程序的“ObjectCreated”事件通知