我有一个带有节点,值和日期时间列的数据框。我想获取每个节点每个月的值从60增长到70所需的最大天数。如果该值保持在60以下或70以上,则该值应为0。如果该值不从60变为70以上或70,则应为0。
df:
rng = pd.date_range('2019-01-01', periods=365, freq='D')
df= pd.DataFrame({'Date': rng, 'Val': np.random.randint(50, 80, size=365), 'Node': 'A'})
df.set_index('Date', inplace=True)
我已经将索引设置为节点,月份和日期,但是我不知道如何获取阈值之间的值计数。
df.set_index(['Node', df.index.month, df.index])['Val'].between(60, 70)
我认为答案应该是每个月应用两次之间的“ Val”列中的连续True值的最大数量。
输出应该是这样的数据框:
df = pd.DataFrame([
{'Node': 'A', 'Month': 1, 'Count': 3},
{'Node': 'A', 'Month': 2, 'Count': 5},
{'Node': 'A', 'Month': 3, 'Count': 0},
{'Node': 'B', 'Month': 1, 'Count': 5},
{'Node': 'B', 'Month': 2, 'Count': 3},
{'Node': 'B', 'Month': 3, 'Count': 2},
...
])
答案 0 :(得分:2)
demo
基本上,对范围内的值进行计数,如果从未达到70,则将其分配为零。 您可以在之后添加一个步骤,以填写由于值小于60而缺少的月份
答案 1 :(得分:1)
如果我理解正确,
一个想法是将groupby
与常规cumsum
和cumcount
一起使用来连续计数直到达到70天。
np.random.seed(0)
np.random.randint(50, 80, size=365)
rng = pd.date_range('2019-01-01', periods=365, freq='D')
df= pd.DataFrame({'Date': rng, 'Val': np.random.randint(50, 80, size=365), 'Node': 'A'})
df.sort_values('Date',inplace=True)
df['C'] = (df.loc[(df["Val"] > 60) & (df["Val"] <= 70)]
.groupby([df["Date"].dt.month, (df['Val'] == 70).cumsum()])).cumcount() + 1
因为我们只希望当月的值达到70,所以如果在给定的月份内未达到70,则需要将计数设置为0,因此我们可以按月过滤并将其返回到列表中,然后使用{{1 }}
isin