根据熊猫中的时间戳差异条件提取值

时间:2019-07-17 11:38:20

标签: python pandas date

我有一个数据集,其中包含每个ID的时间戳和值。每个ID的行数不同,我需要像这样的double for循环:

for ids in IDs:
for index in Date:

现在,我想通过以下方式为每个ID查找时间戳之间的差异:

  • 2天之间的值
  • 7天之内的值

尤其是对于每个ID

  • 如果从第一个值开始,在接下来的2天中,从第一个值开始至少增加0.3 或
  • 如果从第一个值开始,接下来的7天中有一个等于1.5 *第一个值的值

我将该ID存储在一个数据框中,否则将其存储在另一个数据框中。

现在,我的代码如下:

yesDf = pd.DataFrame()
noDf = pd.DataFrame()

for ids in IDs:
for index in Date:
    if ((df.iloc[Date - 1]['Date'] - df.iloc[0]['Date']).days <= 2):
        if (df.iloc[index]['Val'] - df.iloc[index - 1]['Val'] >= 0.3):
            yesDf += IDs['ID']
        noDf += IDs['ID']
    if ((df.iloc[Date - 1]['Date'] - df.iloc[0]['Date']).days <= 7):
        if(df.iloc[Date - 1]['Val'] >= df.iloc[index]['Val'] * 1.5):
            yesDf += IDs['ID']
        noDf += IDs['ID']


 print(yesDf)
 print(noDf)

我得到这些错误:

TypeError: incompatible type for a datetime/timedelta operation [sub]

pandas.errors.NullFrequencyError: Cannot shift with no freq

如何解决此问题? 谢谢

编辑:我的数据框

          Val     ID             Date     
   2199   0.90  0000.0 2017-12-26 11:00:01  
   2201   1.35  0001.0 2017-12-26 11:00:01  
   63540  0.72  0001.0 2018-08-10 11:53:01
   68425  0.86  0001.0 2018-10-14 08:33:01
   42444  0.99  0002.0 2018-02-01 09:25:53
   41474  1.05  0002.0 2018-04-01 08:00:04
   42148  1.19  0002.0 2018-07-01 08:50:00 
   24291  1.01  0004.0 2017-01-01 08:12:02 

例如:对于ID 0001.0,第一个值是1.35,在接下来的2天中,我的起始值至少不会增加0.3,在接下来的7天中,我的起始值也不会增加1.5倍于firsrt值,因此它进入了noDf数据帧。

还有dtypes

 Val               float64
 ID                object
 Date       datetime64[ns]
 Surname            object
 Name               object
 dtype: object

编辑:

修改后的代码结果为:

         Val     ID          Date         Date_diff_cumsum  Val_diff
  24719  2.08  0118.0 2017-01-15 08:16:05       1.0           0.36
  24847  2.17  0118.0 2017-01-16 07:23:04       1.0           0.45
  25233  2.45  0118.0 2017-01-17 08:21:03       2.0           0.73
  24749  2.95  0118.0 2017-01-18 09:49:09       3.0           1.23
 17042  1.78  0129.0 2018-02-05 22:48:17       0.0           0.35

这是正确的。现在,我只需要将单个ID添加到数据框中

1 个答案:

答案 0 :(得分:1)

假设您从ID的第一个值(即第一个时间戳)开始,此答案应该有效。

首先,我添加了'Date_diff_cumsum'列,该列存储ID的第一个日期与行的日期之间的天数差异:

df['Date_diff_cumsum'] = df.groupby('ID').Date.diff().dt.days
df['Date_diff_cumsum'] = df.groupby('ID').Date_diff_cumsum.cumsum().fillna(0)

然后,我添加'Value_diff'列,这是ID的第一个值与行的值之间的差:

df['Val_diff'] = df.groupby('ID')['Val'].transform(lambda x:x-x.iloc[0])

这是为示例DataFrame添加列之后得到的:

    Val     ID      Date                    Date_diff_cumsum    Val_diff
0   0.90    0.0     2017-12-26 11:00:01     0.0                 0.00
1   1.35    1.0     2017-12-26 11:00:01     0.0                 0.00
2   0.72    1.0     2018-08-10 11:53:01     227.0               -0.63
3   0.86    1.0     2018-10-14 08:33:01     291.0               -0.49
4   0.99    2.0     2018-02-01 09:25:53     0.0                 0.00
5   1.05    2.0     2018-04-01 08:00:04     58.0                0.06
6   1.19    2.0     2018-07-01 08:50:00     149.0               0.20
7   1.01    4.0     2017-01-01 08:12:02     0.0                 0.00

最后,返回满足您的问题条件的行:

df[((df['Val_diff']>=0.3) & (df['Date_diff_cumsum']<=2)) |
   ((df['Val'] >= 1.5*(df['Val']-df['Val_diff'])) & (df['Date_diff_cumsum']<=7))]

在这种情况下,它将不返回任何行。

yesDf = df[((df['Val_diff']>=0.3) & (df['Date_diff_cumsum']<=2)) |
           ((df['Val'] >= 1.5*(df['Val']-df['Val_diff'])) & (df['Date_diff_cumsum']<=7))].ID.drop_duplicates().to_frame()

noDf = df[~((df['Val_diff']>=0.3) & (df['Date_diff_cumsum']<=2)) |
           ((df['Val'] >= 1.5*(df['Val']-df['Val_diff'])) & (df['Date_diff_cumsum']<=7))].ID.drop_duplicates().to_frame()

yesDf包含满足条件的ID,noDf包含不满足条件的

我希望这能回答您的问题!