Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
根据python中另一个df中的日期数据填写值_Python_Pandas_Datetime - Fatal编程技术网

根据python中另一个df中的日期数据填写值

根据python中另一个df中的日期数据填写值,python,pandas,datetime,Python,Pandas,Datetime,我想通过匹配日期数据将补充信息从df2添加到df1 df1是主数据帧: x0 x1 x2 x3 x4 x5 ... x10000 Date 1 40 31.05 25.5 25.5 25.5 25 ... 33 2013-11-13 2 35 35.75 36.5 36.5 3

我想通过匹配日期数据将补充信息从df2添加到df1

df1是主数据帧:

            x0      x1      x2      x3      x4      x5      ...  x10000  Date       
1           40      31.05   25.5    25.5    25.5    25      ...    33    2013-11-13
2           35      35.75   36.5    36.5    36.5    36.5    ...    29    2013-09-05
⋮           ⋮       ⋮        ⋮       ⋮       ⋮        ⋮               ⋮
df2是我想添加到df1中的补充天气信息:

year month day  maxtemp mintemp rainfall    wind 
2013    1   1   26.2    20.2     0          32.4
2013    1   2   22.9    20.3     0          10
2013    1   3   24.8    18.4     0          28.8
2013    1   4   26.6    18.3     0          33.5
2013    1   5   28.3    20.9     0          33.4
2013    1   6   28      21.6     0          32.8
2013    1   7   27.5    21.4     0          26.8
2013    1   8   42.3    20.9     0          25.5
2013    1   9   25      21.1     0          20.9
2013    1   10  25.4    20.2     0          14
⋮       ⋮    ⋮   ⋮        ⋮        ⋮           ⋮
我需要将从
df2
中提取的
maxtemp
mintemp
rainment
wind
前100天的
df2
数据,通过与
df1
中的
进行匹配,水平地添加到df1上每行的末尾。因此,
Date
是第100天,而前99天是
Date
之前的99天

预期产出:

     x0  x1    x2   x3   x4   x5   ... x10000 Date       max_t1...max_t100 min_t1...min_t100 rf1... rf100 w1 ... w100
1    40  31.05 25.5 25.5 25.5 25   ...  33    2013-01-01 26.2  ...         20.2  ...          0 ...       32.4...  
2    35  35.75 36.5 36.5 36.5 36.5 ...  29    2013-01-03 24.8. ...         18.4  ...          0 ...       28.8
⋮     ⋮   ⋮      ⋮    ⋮    ⋮     ⋮          ⋮
在哪里

max_t1, ..., max_t100 represent max temperature from day1 to day100(`Date` day);
min_t1, ..., min_t100 represent min temperature from day1 to day100(`Date` day);
rf1, ..., rf100 represent rainfall from day1 to day100(`Date` day);
w1, ..., w100 represent wind from day1 to day100(`Date` day).

这些是新添加的列名(因此总共将有400个新列)。

我建议先在df2中创建400个新列,然后使用将其合并到df1中

分为两个问题:

问题1:计算过去x天的聚合值

回答

适用于您的情况:

In[1]: df2 = pd.DataFrame({"year": [2013, 2013, 2013, 2013, 2013],
                           "month": [1, 1, 1, 1, 1],
                           "day": [1, 2, 3, 4, 5],
                           "mintemp": [26.2, 22.9, 24.8, 11.2, 10],
                           "maxtemp": [28.2, 23.9, 25.8, 22.1, 12]})
       # Create date column (type datetime64[ns])
       df2["date"] = pd.to_datetime((df2[["year", "month", "day"]]))
       # Add the 400 columns needed (I am only adding 2 as an example)
       # If you change 2 to 100 you will get your 100
       colnumber = 2
       # Maxtemp
       for i in range(1, colnumber + 1):
           col_name = "max_t" + str(i)
           df2[col_name] = df2.set_index("date").rolling(i).max()["maxtemp"].values
       # Mintemp
       for i in range(1, colnumber + 1):
           col_name = "min_t" + str(i)
           df2[col_name] = df2.set_index("date").rolling(i).min()["mintemp"].values
       # TODO: Add rainfall and wind

In[2]:df2
Out[2]: 
   year  month  day  mintemp  maxtemp       date  max_t1  max_t2  min_t1  min_t2
0  2013  1      1    26.2     28.2    2013-01-01  28.2   NaN      26.2   NaN    
1  2013  1      2    22.9     23.9    2013-01-02  23.9    28.2    22.9    22.9  
2  2013  1      3    24.8     25.8    2013-01-03  25.8    25.8    24.8    22.9  
3  2013  1      4    11.2     22.1    2013-01-04  22.1    25.8    11.2    11.2  
4  2013  1      5    10.0     12.0    2013-01-05  12.0    22.1    10.0    10.0  
问题2:使用日期列作为公共键水平合并两个数据帧

您必须首先将列转换为datetime(类似的答案),然后使用公共键合并df

In[3]:df1 = pd.DataFrame({"x0": [40, 35, 33, 38],
                          "x1": [31.05, 35.75, 22, 28],
                          "x1000": [33, 29, 20, 18],
                          "Date": ["2013-1-1", "2013-1-2", "2013-1-3", "2013-1-4"]})
    # Creating common key with type datetime64[ns]
    df1["date"] = pd.to_datetime(df1["Date"])

Out[3]:
   x0     x1  x1000      Date       date
0  40  31.05  33     2013-1-1 2013-01-01
1  35  35.75  29     2013-1-2 2013-01-02
2  33  22.00  20     2013-1-3 2013-01-03
3  38  28.00  18     2013-1-4 2013-01-04

In[4]: # Merging
       df1.merge(df2, how="left", left_on=["date"], right_on=["date"])

Out[4]:
   x0     x1  x1000      Date       date  year  month  day  mintemp  maxtemp  max_t1  max_t2  min_t1  min_t2
0  40  31.05  33     2013-1-1 2013-01-01  2013  1      1    26.2     28.2     28.2   NaN      26.2   NaN    
1  35  35.75  29     2013-1-2 2013-01-02  2013  1      2    22.9     23.9     23.9    28.2    22.9    22.9  
2  33  22.00  20     2013-1-3 2013-01-03  2013  1      3    24.8     25.8     25.8    25.8    24.8    22.9  
3  38  28.00  18     2013-1-4 2013-01-04  2013  1      4    11.2     22.1     22.1    25.8    11.2    11.2 
编辑:添加了输出

我假设df1中的日期列是datetime类型。如果不是,则转换它

从这些准备步骤开始:

  • 在df2 convert year/month/day列中,索引(日期时间类型):

  • 设置天数,为其添加列:

    nDays = 3
    
    出于演示目的,我将其设置为仅3,但您可以将其更改为100 或者任何你想要的价值

  • 定义新列的列名(首先导入itertools):

  • 定义一个函数为当前行生成其他列:

    def fn(row):
        d1 = row.Date
        d2 = d1 + pd.Timedelta(nDays - 1, 'D')
        return pd.Series(df2.loc[d1:d2].values.reshape((1, -1),
            order='F').squeeze(), index=cols)
    
  • 现在,整个处理可以在一条
    指令中进行, 将上述函数应用于每一行,并将结果连接到 原始数据帧:

    df1 = df1.join(df1.apply(fn, axis=1))
    
    非常简洁,并且在很大程度上是泛美的解决方案

    为了演示此解决方案的工作原理,我稍微更改了您的数据:

    df1:

       x0     x1    x2    x3       Date
    0  40  31.05  25.5  25.5 2013-01-03
    1  35  35.75  36.5  36.5 2013-01-07
    
    df2(初始内容):

    df2(转换后):

    添加新列后,df1包含:

       x0     x1    x2    x3       Date  max_t1  max_t2  max_t3  min_t1  min_t2  \
    0  40  31.05  25.5  25.5 2013-01-03    24.8    26.6    28.3    18.4    18.3   
    1  35  35.75  36.5  36.5 2013-01-07    27.5    42.3    25.0    21.4    20.9   
    
       min_t3  rf1  rf2  rf3    w1    w2    w3  
    0    20.9  1.0  2.0  3.0  28.8  33.5  33.4  
    1    21.1  5.0  6.0  7.0  26.8  25.5  20.9  
    
    在“100天前”注释后编辑 如果添加的行取自当前日期之前的100天, 更改fn函数中两个“边界日期”的设置方式。比如:

    def fn(row):
        d1 = row.Date - pd.Timedelta(nDays, 'D')
        d2 = row.Date - pd.Timedelta(1, 'D')
        return pd.Series(df2.loc[d1:d2].values.reshape((1, -1), order='F')
            .squeeze(), index=cols)
    
    如何避免增加行数 如果df2在某些日期包含多行,则加入 df1和df2导致输出行数增加

    如果df2的某个日期有3行,则df1的行 使用此日期,结果将仅包含3行(日期相同)

    为了避免这种情况,你必须“抑制”这种重复

    最初我想到的是df2=df2.drop_duplicates(…),但是你写了 一行不能包含一组值,另一行不能包含另一组值, 因此,我们不能随意留下一行而删除另一行(从同一日期起)

    解决这个问题的一个可能方法是在“日期索引”之后 创建时,您应该:

    • 按索引对df2进行分组(每组将包含 特定日期)
    • 计算每列的平均值(忽略可能的NaN值)
    • 将结果保存回df2下
    执行此操作的代码是:

    df2 = df2.groupby(level=0).mean()
    
    然后,您可以加入(如上所述)和输出行的数量
    不应该增长。

    rf1。。。rf100
    0,1?@YusufBaktir不,它们是小数点后1位的数值,那么,您需要接下来100天的平均值还是其他什么?@YusufBaktir不是平均值,只需将相应的值从df2复制并粘贴到df1Oh,好的,新的列类似于
    max_t1,max_t2。。。最大值为100
    。基本上,您希望在df1I中添加日期后的100天。当日期列未排序时,我还没有测试过这一点,因此您可能需要在应用于示例时对其进行排序。谢谢您提供了详细的答案。这是100天前而不是之后的
    日期
    ,很抱歉混淆了
    max_t2
    NaN
    不应该是
    23.9
    ?这是以前的情况。之所以存在NaN,是因为在我注意到一些相邻的日期具有相同的值之前没有数据,例如,
    2013-01-04
    minu t1
    minu t2
    都是11.2。有什么不对劲吗?我刚意识到应该是100天前,而不是
    日期之后。你能考虑一下吗?很抱歉造成混淆,在将旧的
    fn
    替换为新的
    fn之后,我得到了这个
    TypeError:(-:'str'和'Timedelta''不支持的操作数类型,发生在索引0')
    。我做错了吗?检查df1中的日期列是否为datetime类型。我一开始就写了,现在可以了!但当我将
    nDays
    增加到100时,它返回了
    ValueError:列重叠但没有指定后缀:Index(['maxtemp1'、'maxtemp2'、'mintemp1'、'mintemp2'、'mintemp3'、'rainwall1'、'rainwall2'、'rainwall3'、'wind1'、'wind2'、'wind3'],dtype='object'))
    必须在设置nDays值后执行指令设置cols。从您的消息(从1到3的数字)中,我看到您执行此指令时,nDays==3。
                maxtemp  mintemp  rainfall  wind
    2013-01-01     26.2     20.2         0  32.4
    2013-01-02     22.9     20.3         0  10.0
    2013-01-03     24.8     18.4         1  28.8
    2013-01-04     26.6     18.3         2  33.5
    2013-01-05     28.3     20.9         3  33.4
    2013-01-06     28.0     21.6         4  32.8
    2013-01-07     27.5     21.4         5  26.8
    2013-01-08     42.3     20.9         6  25.5
    2013-01-09     25.0     21.1         7  20.9
    2013-01-10     25.4     20.2         8  14.0
    
       x0     x1    x2    x3       Date  max_t1  max_t2  max_t3  min_t1  min_t2  \
    0  40  31.05  25.5  25.5 2013-01-03    24.8    26.6    28.3    18.4    18.3   
    1  35  35.75  36.5  36.5 2013-01-07    27.5    42.3    25.0    21.4    20.9   
    
       min_t3  rf1  rf2  rf3    w1    w2    w3  
    0    20.9  1.0  2.0  3.0  28.8  33.5  33.4  
    1    21.1  5.0  6.0  7.0  26.8  25.5  20.9  
    
    def fn(row):
        d1 = row.Date - pd.Timedelta(nDays, 'D')
        d2 = row.Date - pd.Timedelta(1, 'D')
        return pd.Series(df2.loc[d1:d2].values.reshape((1, -1), order='F')
            .squeeze(), index=cols)
    
    df2 = df2.groupby(level=0).mean()