从if循环子集熊猫时间序列数据帧

时间:2019-05-24 14:58:37

标签: python python-3.x pandas loops spyder

请让我知道我的问题的标题是否正确-我认为我需要循环if语句来解决以下问题-我一般是Python和编程的新手,所以不知道该术语是否正确正确。

我正在使用Spyder,从事一个研究项目。

我需要在现有数据帧(df)中创建一个新变量,该变量提供以下逻辑:

  •   

    如果在T1和T2之间记录了任何变量(e2或e3)中的任何一个,则在时间T1(列e1中的数字1第一次出现)和时间T2(在e1中的第二个数字)之间或者 T1和T2之间的v1值大于1,然后在T1和T2之间的“结果”新列中放置1。

  •   

    如果在T2和T3之间记录了任何变量(e2或e3)中的任何一个,则在时间T2(在e1列中第二次出现数字1)和时间T3(在e1中第3个数字)之间或者 T2和T3之间的v1值大于1,然后在T2和T3之间的新列“结果”中放置1。

在T3和T4等之间

根据上述内容,我将基于“结果”中为1的所有行创建数据的子集,以供进一步分析。

要重新创建df的一小部分:

import pandas as pd
import numpy as np
import datetime


df = pd.DataFrame({'e1' : [1,np.nan,np.nan,1,np.nan,1,np.nan,np.nan,1,np.nan,np.nan,1,np.nan],
                    'e2' : [np.nan,1,np.nan,np.nan,np.nan,np.nan,np.nan,np.nan,np.nan,np.nan,np.nan,np.nan,np.nan],
                    'e3' : [np.nan,np.nan,np.nan,np.nan,1,np.nan,np.nan,np.nan,np.nan,np.nan,np.nan,np.nan,np.nan],
                    'v1' : [1,1,1,1,1,1,1,1,1,1.2,1.5,1,1],},
                        index=pd.date_range('2019-05-02T00:00:00', '2019-05-02T01:00:00', freq='5T'))

结果应为:

'result' : [1,1,1,1,1,np.nan,np.nan,np.nan,np.nan,1,1,np.nan,np.nan]

我希望这是有道理的。

谢谢!

编辑31.05.2019

建议的解决方案适用于大多数实例,但是以严重的方式失败:

我已经对样本数据进行了编辑,以包含一个实例,该实例在00:25:00的e1和e2中均存在观测值。

import pandas as pd
import numpy as np
import datetime

df = pd.DataFrame({'e1' : [1,np.nan,np.nan,1,np.nan,1,np.nan,np.nan,1,np.nan,np.nan,1,np.nan],
                    'e2' : [np.nan,1,np.nan,np.nan,np.nan,1,np.nan,np.nan,np.nan,np.nan,np.nan,np.nan,np.nan],
                    'e3' : [np.nan,np.nan,np.nan,np.nan,1,np.nan,np.nan,np.nan,np.nan,np.nan,np.nan,np.nan,np.nan]},
                        index=pd.date_range('2019-05-02T00:00:00', '2019-05-02T01:00:00', freq='5T'))

问题

我遇到的问题是建议的解决方案报告了00:25:00到00:40:00之间的结果,我希望结果中不包括该结果。我希望代码分析e1列中1的时间,不包括e1中观察值的时间。

我希望这是有道理的...

1 个答案:

答案 0 :(得分:0)

这可以通过屏蔽和分组方式来完成:

# if there is an event at that time
events = df[['e2','e3']].notna().any(axis=1)

# if v1 > 1 at given time
v1g1 = df['v1'].gt(1)

# mask
mask = v1g1 | events

# group the events by e1 
df['result'] = mask.groupby(df.e1.fillna(0).cumsum()).transform('any')

# if you want 1 and NaN:
df['result'] = np.where(mask.groupby(df.e1.fillna(0).cumsum()).transform('any'),
                        1, np.nan)

输出为True以外的False1, NaN

                        e1      e2      e3      v1      result
2019-05-02 00:00:00     1.0     NaN     NaN     1.0     True
2019-05-02 00:05:00     NaN     1.0     NaN     1.0     True
2019-05-02 00:10:00     NaN     NaN     NaN     1.0     True
2019-05-02 00:15:00     1.0     NaN     NaN     1.0     True
2019-05-02 00:20:00     NaN     NaN     1.0     1.0     True
2019-05-02 00:25:00     1.0     NaN     NaN     1.0     False
2019-05-02 00:30:00     NaN     NaN     NaN     1.0     False
2019-05-02 00:35:00     NaN     NaN     NaN     1.0     False
2019-05-02 00:40:00     1.0     NaN     NaN     1.0     True
2019-05-02 00:45:00     NaN     NaN     NaN     1.2     True
2019-05-02 00:50:00     NaN     NaN     NaN     1.5     True
2019-05-02 00:55:00     1.0     NaN     NaN     1.0     False
2019-05-02 01:00:00     NaN     NaN     NaN     1.0     False
相关问题