Python pandas数据帧:围绕关键日期进行过滤

时间:2017-06-13 05:02:18

标签: python pandas filter

我有一个pandas日期框架df,其索引为每日DatetimeIndex,附加列为historical_sales

如果我们想过滤历史数据大于大数的过去几天,比如说200,那就够了:

df.loc[df['historical_sales'>200]]

我想知道,如果我们想要在销售前后的5天内和之后的5天内探讨销售模式,那该怎么办呢? 200?

非常感谢。

4 个答案:

答案 0 :(得分:1)

我认为您不需要按列表推导获取所有索引值,然后按loc选择。

还必须使用numpy.concatenatenumpy.unique一起加入所有索引以删除重复项。

np.random.seed(100)
rng = pd.date_range('2017-04-03', periods=20)
df = pd.DataFrame({'historical_sales': np.random.choice([100,200,300], size=20)}, index=rng)
print (df)
            historical_sales
2017-04-03               100
2017-04-04               100
2017-04-05               100
2017-04-06               300
2017-04-07               300
2017-04-08               100
2017-04-09               300
2017-04-10               200
2017-04-11               300
2017-04-12               300
2017-04-13               300
2017-04-14               300
2017-04-15               200
2017-04-16               100
2017-04-17               100
2017-04-18               100
2017-04-19               100
2017-04-20               300
2017-04-21               100
2017-04-22               200
idxmask = df.index[df['historical_sales']>200]
print (idxmask)
DatetimeIndex(['2017-04-06', '2017-04-07', '2017-04-09', '2017-04-11',
               '2017-04-12', '2017-04-13', '2017-04-14', '2017-04-20'],
              dtype='datetime64[ns]', freq=None)

#in real data change 1 to 5 for 5 days
temp_index = [df.loc[timestamp - pd.Timedelta(1, unit='d') : 
                     timestamp + pd.Timedelta(1, unit='d')].index for timestamp in idxmask]
idx = np.unique(np.concatenate(temp_index))

df1 = df.loc[idx]
print (df1)
            historical_sales
2017-04-05               100
2017-04-06               300
2017-04-07               300
2017-04-08               100
2017-04-09               300
2017-04-10               200
2017-04-11               300
2017-04-12               300
2017-04-13               300
2017-04-14               300
2017-04-15               200
2017-04-19               100
2017-04-20               300
2017-04-21               100

答案 1 :(得分:0)

您可能希望进行范围切片:http://pandas.pydata.org/pandas-docs/stable/indexing.html#selection-by-position

应该看起来像这样(代码是伪代码):

great_sales_df = df.loc[df['historical_sales'>200]]
for sale in great_sales_df:
   sales_date = great_sales_df["date"]
   sales_before = sales_date + pd.DateOffset(-5)
   sales_after =  sales_date + pd.DateOffset(+5)
   pattern_df = df.iloc[sales_before:sales_after]

此代码不起作用,但我认为方向是正确的。

答案 2 :(得分:0)

为了清楚起见,我添加了一个new列,对于感兴趣的行设置为1。为了便于验证,在下面的代码中,窗口日期的数量保持为1而不是5,

import pandas as pd
import numpy as np
from datetime import datetime, timedelta

df = pd.DataFrame(data=np.random.rand(51),index=pd.date_range('2015-04-20','2015-06-09'),columns=['A'])
idx = df[df.A >0.5].index

df["new"] = 0

for date in idx:
    current_date = date.to_pydatetime()
    start = current_date - timedelta(days=1)
    end = current_date + timedelta(days=1)

    df.loc[start:current_date]["new"] = 1
    df.loc[current_date:end]["new"] = 1


print(df)

答案 3 :(得分:0)

当我需要在前后处理行时,我只需执行一次移位。

df['preceeding_5th_day'] = df['historical_sales'].shift(5)
df['following_5th_day'] = df['historical_sales'].shift(-5)

然后,您可以简单地进行检查并执行

df.loc[df['historical_sales'>200]]

然后,所选行还将包含有关第5天之前和之后的列。这种方式很简单。