请让我知道我的问题标题是否准确 - 我认为我需要一个循环if语句来解决下面的问题 - 我是Python和总体编程的新手,所以不知道术语是否正确。
我正在使用Spyder,从事研究项目。
我需要在现有数据框架(DF(中创建一个新变量,该变量提供以下逻辑:
-
在时间T1(E1列中的数字1的第1个出现(和时间T2(E1中的2nd 1(之间,如果对于任何变量(E2或E3(之间的T1和T2之间有1个记录(E3(或 T1和T2之间的V1值大于1,然后将1放在新列中,称为T1和T2之间的"结果"。
-
在时间T2(E1列中的数字1的第2个出现(和时间T3(E1中的第3个(之间,如果任何变量(E2或E3(在T2和T3之间记录了1个(E3(或 T2和T3之间的V1值大于1,然后将1放在新列中,称为T2和T3之间的"结果"。
在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中的观察时间。
我希望这是有道理的...
这可以通过masking和groupby来完成:
# 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
, False
,而不是 1, 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