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

尼尔辛拉伯

我想通过匹配日期数据将补充信息从 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
⋮       ⋮    ⋮   ⋮        ⋮        ⋮           ⋮

我需要添加前述100天的maxtempmintemprainfallwind从提取的数据df2,对所述DF1每行的端部水平与由匹配yearmonthdayDatedf1所以Date是100当天和前99天,都在99天Date

预期输出:

     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 个新列)。

瓦尔迪博

我假设df1中的Datedatetime类型。如果不是,请转换它。

从这样的准备步骤开始:

  1. df2 中转换//列的索引(日期时间类型):

    df2 = df2.set_index(pd.to_datetime(df2.year * 10000 + df2.month * 100
        + df2.day, format='%Y%m%d')).drop(columns=['year', 'month', 'day'])
    
  2. 设置天数,为其添加列:

    nDays = 3
    

    出于演示目的,我仅将其设置为3,但您可以将其更改为100或您希望的任何值。

  3. 为新列定义列名(首先导入 itertools):

    cols = [ x + str(y) for x, y in itertools.product(
        ['max_t', 'min_t', 'rf', 'w'], range(1, nDays + 1)) ]
    
  4. 定义一个函数来为当前行生成附加列:

    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))

相当简洁,而且在很大程度上是Pandasonic解决方案。

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

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(初始内容):

   year  month  day  maxtemp  mintemp  rainfall  wind
0  2013      1    1     26.2     20.2         0  32.4
1  2013      1    2     22.9     20.3         0  10.0
2  2013      1    3     24.8     18.4         1  28.8
3  2013      1    4     26.6     18.3         2  33.5
4  2013      1    5     28.3     20.9         3  33.4
5  2013      1    6     28.0     21.6         4  32.8
6  2013      1    7     27.5     21.4         5  26.8
7  2013      1    8     42.3     20.9         6  25.5
8  2013      1    9     25.0     21.1         7  20.9
9  2013      1   10     25.4     20.2         8  14.0

df2(转换后):

            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

添加新列后,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包含某些日期的行,则将df1df2 连接会导致输出行数增加。

如果DF2已经有一段日子,例如有3行的一个排从DF1与此日期的结果将只包含3行(具有相同的日期)。

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

最初我想过df2 = df2.drop_duplicates(...),但是您写道,一行可以包含一组值和另一行 - 另一组,因此我们不能随意保留一行并删除其他行(从同一日期开始) )。

此问题的一种可能解决方案是,在创建“日期索引”之后,您应该:

  • 按索引对df2分组(每个组将包含特定日期的所有行),
  • 计算每列的平均值(省略可能的NaN值),
  • 将结果保存回df2

执行此操作的代码是:

df2 = df2.groupby(level=0).mean()

然后就可以join了(如上所述),输出行数应该不会增长。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

根据来自另一个 df 的值填写 1 df 中多列的 NA 值

根据另一个数据框中的日期过滤数据框中的值

根据Python中另一个数据框的列表更新具有更早日期的值

根据日期范围将数据框中的值除以另一个数据框中的日期

PostgreSQL根据在另一个表中输入的值自动填写字段

根据另一个df中的值填充新的df大熊猫

根据另一个 df 更改 df1 列中的值

根据条件将df中的列除以另一个df值

根据另一个df中的特定索引替换一个df中的值

Python根据另一个数据框中的列值匹配列名

根据R中另一个向量的索引更改df列中的值

如何根据另一个数据框中的日期时间条件从数据框中选择列的值?

根据范围中的日期更新另一个工作表中的列中的值

根据一个键将数据从df复制到多列中的另一个df

根据另一个df中的列计算一个df中的行数

如何根据另一个数据框pyspark填写空值

如果多列中的值与另一个数据框匹配,则根据 pandas 的日期范围获取总和

Python - 多次从另一个df中查找一个值

根据另一个中的值填充新的pandas df列

根据 dplyr 中的另一个 df 更新值

根据另一个更改 df 列中的某些值

根据python中另一个列值的顺序设置数据框中的列值

根据另一个数据框中的值更改 Python 数据框中的值

根据日期从另一个数据框中过滤熊猫数据框

Python根据另一个数据框值中存在的列索引填充数据框值

如何使用键在python数据帧中查找值,并使用另一个键将其与另一个df中的另一个值求和

Scala-根据另一个DF中的事务过滤DF中每个ID的数据

根据另一个df中最小/最大日期范围内的日期在熊猫中合并/加入

根据另一个表中的并发日期范围划分列值?