从循环 if 语句子集熊猫时间序列数据帧
Posted
技术标签:
【中文标题】从循环 if 语句子集熊猫时间序列数据帧【英文标题】:Subset pandas timeseries dataframe from looping if statement 【发布时间】:2019-10-11 04:55:09 【问题描述】:请让我知道我的问题的标题是否准确 - 我认为我需要一个循环 if 语句来解决以下问题 - 我是 Python 和一般编程的新手,所以不知道术语是否正确正确。
我正在使用 Spyder,正在做一个研究项目。
我需要在现有数据框 (df) 中创建一个新变量,该变量提供以下逻辑:
在时间 T1(数字 1 在 e1 列中第一次出现)和时间 T2(在 e1 中第二次出现)之间,如果在 T1 和 T2 之间记录了任何变量(e2 或 e3)的 1 或者 T1 和 T2 之间的 v1 的值大于 1,然后在 T1 和 T2 之间名为“结果”的新列中放置一个 1。
在时间 T2(数字 1 在 e1 列中第二次出现)和时间 T3(在 e1 中第三次出现 1)之间,如果任何变量(e2 或 e3)在 T2 和 T3 之间记录为 1 或者 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】:这可以通过 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
【讨论】:
嗨,这不起作用。我有一个问题,在我的数据中,如果我在 e1 中的事件同时有一个观察值(在 e2 或 e3 中),它会将其包含在最终结果中。我需要代码在 T1 和 T2 之间的时间工作,不包括 T1 和 T2。我已经对我的原始问题添加了一个编辑。谢谢。 我已使用更新的数据示例编辑了原始问题,以演示我遇到的问题。问题是解决方案包括 T1 和 T2,但我需要解决方案不包括 T1 和 T2,而是使用 T1 和 T2 之间的时间。 抱歉,我的结果列显示不正确。我会编辑。以上是关于从循环 if 语句子集熊猫时间序列数据帧的主要内容,如果未能解决你的问题,请参考以下文章