根据python中的日期提取和重塑数据

时间:2017-05-17 15:09:04

标签: python pandas dataframe

我正在寻找一些帮助来决定最有效的方法。我有一个具有特定日期的数据集,没有常规的时间步长。对于这些日期中的每一个,我想创建一个值,范围从日期之前的10天到日期之后的3天。我需要的数据是2列,日期为1,值为另一列。

想到的是使用循环来比较日期并提取 我需要的价值观。我想可能有更好的方法,使用numpy \ pandas或者其他什么?我觉得我的想法是一种相当复杂的事情。

编辑: 所以数据就是这样的。

Date        Values     
2014-02-09  38.351
2014-02-10  38.281
2014-02-11  38.146
2014-02-12  38.205
2014-02-13  38.428
2014-02-14  38.449
2014-02-15  38.540
2014-02-16  38.586
2014-02-17  38.489
2014-02-18  38.552
2014-02-19  38.580
2014-02-20  38.447
2014-02-21  38.336
2014-02-22  38.284
2014-02-23  38.183
2014-02-24  38.143
2014-02-25  38.146
2014-02-26  38.221
2014-02-27  38.182
2014-02-28  38.170 

一行的样本输出将采用以下形式:

                  t-10     t-9     t-8     t-7     t-6     t-5     t-4     t-3  \
    Date                                                                         
    2014-02-19  37.728  37.753  37.652  37.549  37.474  37.407  37.344  37.278   

                   t-2    t-1       t     t+1     t+2     t+3  
    Date                                                       
    2014-02-19  37.221  37.18  37.125  37.138  37.414  37.394  

当t = 2014-02-19时,提取t-10到t + 3的值。我需要在几个不同的日期做到这一点。

编辑:我需要使用这些特定日期。值t-10到t + 3,其中t为以下每个日期,例如。这就是我考虑使用循环的原因。但这似乎是一种混乱的做事方式。

              Date
    0   2014-11-22
    1   2014-12-28
    2   2015-01-02
    3   2015-02-04
    4   2015-02-16
    5   2015-02-28
    6   2015-03-12
    7   2015-03-24
    8   2015-04-05
    9   2015-04-15
    10  2015-04-17
    11  2015-04-20
    12  2015-11-07
    13  2015-11-10
    14  2015-11-19
    15  2015-11-22
    16  2015-11-29
    17  2015-12-01
    18  2015-12-04
    19  2015-12-11

2 个答案:

答案 0 :(得分:1)

完全使用您提供的表格,我在调用它们之前首先创建了列,只是为了清晰起见。

df['Date'] = pd.to_datetime(df['Date'],format='%Y-%m-%d')

for daysDelta in range(-10,4):
        key = 't'+str(daysDelta)
        df[key] = np.nan

当我查看前五行时,我给了我这个:

        Date    Values t-10 t-9 t-8 t-7 t-6 t-5 t-4 t-3 t-2 t-1 t0  t1  t2  t3
0   2014-09-02  38.351  NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
1   2014-10-02  38.281  NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2   2014-11-02  38.146  NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
3   2014-12-02  38.205  NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
4   2014-02-13  38.428  NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN

然后,您想循环遍历每一行,并使用索引(哪一行分配)和(哪一列)为每列分配正确的值:< / p>

for index, row in df.iterrows():
    for daysDelta in range(-10,4): #loops through days
        key = 't'+str(daysDelta)

        # will be true if the difference of days is the one you are looking for
        booleanTimeDelta = ((df.loc[:,'Date'] -row['Date']).dt.days == daysDelta) 

        # if any are true find them and assign it  
        if any(booleanTimeDelta):
            df.loc[index:index+1,key] = df.loc[booleanTimeDelta,'Values'].values

这是您的示例的输出

         Date  Values    t-10     t-9     t-8     t-7     t-6     t-5     t-4     t-3     t-2     t-1      t0      t1      t2      t3
0  2014-09-02  38.351     NaN     NaN     NaN     NaN     NaN     NaN     NaN     NaN     NaN     NaN  38.351     NaN     NaN     NaN
1  2014-10-02  38.281     NaN     NaN     NaN     NaN     NaN     NaN     NaN     NaN     NaN     NaN  38.281     NaN     NaN     NaN
2  2014-11-02  38.146     NaN     NaN     NaN     NaN     NaN     NaN     NaN     NaN     NaN     NaN  38.146     NaN     NaN     NaN
3  2014-12-02  38.205     NaN     NaN     NaN     NaN     NaN     NaN     NaN     NaN     NaN     NaN  38.205     NaN     NaN     NaN
4  2014-02-13  38.428     NaN     NaN     NaN     NaN     NaN     NaN     NaN     NaN     NaN     NaN  38.428  38.449  38.540  38.586
5  2014-02-14  38.449     NaN     NaN     NaN     NaN     NaN     NaN     NaN     NaN     NaN  38.428  38.449  38.540  38.586  38.489
6  2014-02-15  38.540     NaN     NaN     NaN     NaN     NaN     NaN     NaN     NaN  38.428  38.449  38.540  38.586  38.489  38.552
7  2014-02-16  38.586     NaN     NaN     NaN     NaN     NaN     NaN     NaN  38.428  38.449  38.540  38.586  38.489  38.552  38.580
8  2014-02-17  38.489     NaN     NaN     NaN     NaN     NaN     NaN  38.428  38.449  38.540  38.586  38.489  38.552  38.580  38.447
9  2014-02-18  38.552     NaN     NaN     NaN     NaN     NaN  38.428  38.449  38.540  38.586  38.489  38.552  38.580  38.447  38.336
10 2014-02-19  38.580     NaN     NaN     NaN     NaN  38.428  38.449  38.540  38.586  38.489  38.552  38.580  38.447  38.336  38.284
11 2014-02-20  38.447     NaN     NaN     NaN  38.428  38.449  38.540  38.586  38.489  38.552  38.580  38.447  38.336  38.284  38.183
12 2014-02-21  38.336     NaN     NaN  38.428  38.449  38.540  38.586  38.489  38.552  38.580  38.447  38.336  38.284  38.183  38.143
13 2014-02-22  38.284     NaN  38.428  38.449  38.540  38.586  38.489  38.552  38.580  38.447  38.336  38.284  38.183  38.143  38.146
14 2014-02-23  38.183  38.428  38.449  38.540  38.586  38.489  38.552  38.580  38.447  38.336  38.284  38.183  38.143  38.146  38.221
15 2014-02-24  38.143  38.449  38.540  38.586  38.489  38.552  38.580  38.447  38.336  38.284  38.183  38.143  38.146  38.221  38.182
16 2014-02-25  38.146  38.540  38.586  38.489  38.552  38.580  38.447  38.336  38.284  38.183  38.143  38.146  38.221  38.182  38.182
17 2014-02-26  38.221  38.586  38.489  38.552  38.580  38.447  38.336  38.284  38.183  38.143  38.146  38.221  38.182  38.182     NaN
18 2014-02-27  38.182  38.489  38.552  38.580  38.447  38.336  38.284  38.183  38.143  38.146  38.221  38.182  38.182     NaN     NaN

答案 1 :(得分:0)

我会对你想要的东西做出许多假设,但我想我理解你的问题。你有类似的东西。

In [1]: df
Out[1]: 
    dates   numbers sumOfDates
0   2016-02-04  1   NaN
1   2016-02-13  2   NaN
2   2016-01-25  4   NaN
3   2016-01-16  1   NaN
4   2016-01-27  3   NaN
5   2016-01-13  4   NaN
6   2016-01-15  5   NaN
7   2016-01-29  1   NaN
8   2016-01-11  3   NaN
9   2016-01-17  4   NaN

所有那些NaN都在哪里

这里数字是你谈到的价值观。然后,通过遍历定位所需范围内的所有文件的行,这应该是简单的。然后只需应用总和并将其分配给 sumOfDates 中适当的行

for index, row in df.iterrows():
    df.loc[index,'sumOfDates'] = df[(df.dates >(row['dates']-pd.DateOffset(10)))].loc[(df.dates <
    (row['dates']+pd.DateOffset(3)))].numbers.sum()

输出应如下:

df
dates   numbers sumOfDates
0   2016-02-04  1   5.0
1   2016-02-13  2   3.0
2   2016-01-25  4   12.0
3   2016-01-16  1   17.0
4   2016-01-27  3   8.0
5   2016-01-13  4   12.0
6   2016-01-15  5   17.0
7   2016-01-29  1   8.0
8   2016-01-11  3   7.0
9   2016-01-17  4   17.0

如果我错了,请发布一些示例,以便我们查看这是否是您正在寻找的内容。但我希望你能看到你能用熊猫做些什么。