根据日期合并Pandas Dataframes

时间:2018-01-12 18:02:13

标签: python pandas dataframe

我希望根据日期合并两个pandas DataFrames。问题是第二个数据帧不包括第一个数据帧的每个日期。我需要使用df1中的每个日期和df2的最新值。

+-------------+---------------+-------------+
| DataFrame 1 |               |             |
+-------------+---------------+-------------+
| Date        |  Sales loc1   |  Sales loc2 |
| 1/1/17      |  100          |  95         |
| 1/2/17      |  125          |  124        |
| 1/3/17      |  115          |  152        |
| ...         |               |             |
| 2/1/17      |  110          |  111        |
+-------------+---------------+-------------+


+-------------+---------+------+
| DataFrame 2 |         |      |
+-------------+---------+------+
| Date        |  exp    |  loc |
| 1/1/17      |  100    |  1   |
| 1/1/17      |  125    |  2   |
| 2/1/17      |  115    |  1   |
| 2/1/17      |  110    |  2   |
+-------------+---------+------+


+---------------+---------------+--------------+------------+-------------+
| New Dataframe |               |              |            |             |
+---------------+---------------+--------------+------------+-------------+
| Date          |  Sales loc1   |  Sales loc2  |  exp loc1  |  exp loc2   |
| 1/1/17        |  100          |  95          |  100       |  125        |
| 1/2/17        |  125          |  124         |  100       |  125        |
| 1/3/17        |  115          |  152         |  100       |  125        |
| ...           |               |              |            |             |
| 2/1/17        |  110          |  111         |  115       |  110        |
+---------------+---------------+--------------+------------+-------------+

df2中的值将用于多个单元格,直到df2中有一个新值。

非常感谢你的时间。

1 个答案:

答案 0 :(得分:1)

Date中同一日期可以包含任意行数的通用解决方案,

  1. 首先,使用df1
  2. 合并df2merge
  3. 接下来,使用groupby + apply展平数据框
  4. 最后,使用renameadd_prefix
  5. 进行一些清理以修复列名称

    v = df1.merge(df2[['Date', 'exp']])\
           .groupby(df1.columns.tolist())\
           .exp\
           .apply(pd.Series.tolist)
    
    df = pd.DataFrame(v.tolist(), index=v.index)\
           .rename(columns=lambda x: x + 1)\
           .add_prefix('exp loc')\
           .reset_index()
    
    df
    
         Date  Sales loc1  Sales loc2  exp loc1  exp loc2
    0  1/1/17         100          95       100       125
    1  2/1/17         110         111       115       110
    

    如果Date每个df2只有两个(或一般来说,N个)行,那么这个另一个解决方案应该可以正常运行

    n = 2
    v = pd.DataFrame(
         df2.exp.values.reshape(-1, n), 
         index=df2.Date.unique(), 
         columns=range(1, n + 1)
    ).add_prefix('exp loc')\
     .rename_axis('Date')\
     .reset_index()
    

    现在,它只是df1Date的简单合并。

    df1.merge(v, on='Date')
    
         Date  Sales loc1  Sales loc2  exp loc1  exp loc2
    0  1/1/17         100          95       100       125
    1  2/1/17         110         111       115       110
    

    或者,作为@A。 Leistra指出,使用左外部合并可能需要不同类型的结果:

    df1.merge(v, how='left', on='Date').ffill()
    
         Date  Sales loc1  Sales loc2  exp loc1  exp loc2
    0  1/1/17         100          95     100.0     125.0
    1  1/2/17         125         124     100.0     125.0
    2  1/3/17         115         152     100.0     125.0
    3  2/1/17         110         111     115.0     110.0