首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >第一次和最后一次出现日志条目

第一次和最后一次出现日志条目
EN

Stack Overflow用户
提问于 2020-05-07 23:36:50
回答 1查看 40关注 0票数 1

我知道在stackoverflow上已经有很多类似的问题,但我就是找不到任何东西,也想不出我自己的解决方案……我们开始吧:

我对一组不断变化的数据X运行一致性检查,每次运行都可能会发现一些冲突。我可以用一个独特的key来识别违规的案例。一旦在原始数据集X中解决了冲突,该冲突显然会从检查中消失。违规可能会在以后重新出现,然后应该被视为新的。

每次运行检查时,我都会创建一个日志文件,其中记录了违规的datekey

从此日志文件中,我想提取日志文件中处于打开状态的案例/违规的数量,以及在任何日期累计关闭的案例的数量:

这是左表的另一个变换,它可能有助于理解结果( (.)中的数字)请参考左表中的对应行):

AAA在2020年5月1日开放,2020年5月4日关闭,因为2020年5月4日没有AAA的条目,但我们知道测试是在那个日期运行的(6)。

AAA在2020年5月5日关闭后再次打开,并在2020年5月7日关闭,因为测试在那一天运行,而AAA不再出现(8)。5/6/2020从未出现过。

BBB在2020年5月2日开放,并在2020年5月7日期间出现,因此从未关闭。

下面是框架代码:

代码语言:javascript
复制
df = pd.DataFrame(
    {
        "date": [
            "5/1/2020",
            "5/2/2020",
            "5/3/2020",
            "5/5/2020",
            "5/2/2020",
            "5/3/2020",
            "5/4/2020",
            "5/5/2020",
            "5/7/2020",
        ],
        "key": ["AAA"] * 4 + ["BBB"] * 5,
    }
)
df['date'] = df['date'].astype("datetime64")

我相信我必须使用日期阶梯(date_ladder = df[['date']].drop_duplicates().sort_values(by='date')),并与df进行外部合并,以获得所有日期的每个键的值,然后从那里继续。但是我已经在那里创建合并失败了。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-05-08 16:54:16

所以,这是在睡了一觉之后的尝试…首先,我们将添加一个虚拟变量,然后在数据帧上旋转,并再次将其融化:

代码语言:javascript
复制
df['v'] = True
pvt = df.pivot_table(index='date', columns='key', values='v').fillna(False)
df2 = pvt.reset_index().melt(id_vars='date')
"""
df2:
         date  key  value
0  2020-05-01  AAA   True
1  2020-05-02  AAA   True
2  2020-05-03  AAA   True
3  2020-05-04  AAA  False
4  2020-05-05  AAA   True
5  2020-05-07  AAA  False
6  2020-05-01  BBB  False
7  2020-05-02  BBB   True
8  2020-05-03  BBB   True
9  2020-05-04  BBB   True
10 2020-05-05  BBB   True
11 2020-05-07  BBB   True
"""

现在我们将数据帧移位1,然后检查是否存在从TrueFalse的切换(反之亦然),这表明原始日志文件中出现或消失了一条记录:

代码语言:javascript
复制
df2['switch'] = (df2['value'] ^ df2.shift()['value']) |( (df2['key']!=df2.shift()['key']) & df2['value'])
df2['start'] = df2['switch'] & df2['value']
df2['end'] = df2['switch'] & ~df2['value']

df2['status'] = ''
df2.loc[df2['start'], 'status'] = 'Start'
df2.loc[df2['end'], 'status'] = 'End'
"""
         date  key  value  switch  start    end status
0  2020-05-01  AAA   True    True   True  False  Start
1  2020-05-02  AAA   True   False  False  False       
2  2020-05-03  AAA   True   False  False  False       
3  2020-05-04  AAA  False    True  False   True    End
4  2020-05-05  AAA   True    True   True  False  Start
5  2020-05-07  AAA  False    True  False   True    End
6  2020-05-01  BBB  False   False  False  False       
7  2020-05-02  BBB   True    True   True  False  Start
8  2020-05-03  BBB   True   False  False  False       
9  2020-05-04  BBB   True   False  False  False       
10 2020-05-05  BBB   True   False  False  False       
11 2020-05-07  BBB   True   False  False  False       
"""

我们可以用pd.melt()压缩一下

代码语言:javascript
复制
df3 = df2.loc[df2['status']!=''].melt(id_vars=['key', 'status'], value_vars='date', value_name='date').drop('variable', axis=1)
"""
   key status       date
0  AAA  Start 2020-05-01
1  AAA    End 2020-05-04
2  AAA  Start 2020-05-05
3  AAA    End 2020-05-07
4  BBB  Start 2020-05-02
"""

下一步是按日期对数据进行排序,因为我们想知道在任何时候有多少项处于打开或关闭状态。

代码语言:javascript
复制
df4 = df2.sort_values(by='date')
df4['opened'] = df4['start'].cumsum()
df4['closed'] = df4['end'].cumsum()
"""
         date  key  value  switch  ...    end  status opened  closed
0  2020-05-01  AAA   True    True  ...  False   Start      1       0
6  2020-05-01  BBB  False   False  ...  False              1       0
1  2020-05-02  AAA   True   False  ...  False              1       0
7  2020-05-02  BBB   True    True  ...  False   Start      2       0
2  2020-05-03  AAA   True   False  ...  False              2       0
8  2020-05-03  BBB   True   False  ...  False              2       0
3  2020-05-04  AAA  False    True  ...   True     End      2       1
9  2020-05-04  BBB   True   False  ...  False              2       1
4  2020-05-05  AAA   True    True  ...  False   Start      3       1
10 2020-05-05  BBB   True   False  ...  False              3       1
5  2020-05-07  AAA  False    True  ...   True     End      3       2
11 2020-05-07  BBB   True   False  ...  False              3       2
"""

最后,我们将运行一个groupby(),计算在特定日期打开了多少个项目,并绘制结果:

代码语言:javascript
复制
result = df4.groupby('date').agg(opened=pd.NamedAgg(column='opened', aggfunc='max'), closed = pd.NamedAgg(column='closed', aggfunc='max'))
result['open_on'] = result['opened']-result['closed']
result[['closed', 'open_on']].plot.area()

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61661846

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档