【问题标题】:Pandas vectorization with two dataframe带有两个数据框的 Pandas 矢量化
【发布时间】:2021-10-11 00:05:58
【问题描述】:

假设我有以下两个数据框。数据帧 A 和数据帧 B。

DataFrame A 有四列。年、月、日和温度。 (例如 2021 || 7 || 5 || 23)。目前,DataFrame A 中的一些温度单元格是 NaN。

DataFrame B 有两列。日期和温度。 (例如 2021/7/7 || 28)

DataFrame A 和 DataFrame B 的时间间隔不同。 DataFrame A 的时间间隔小于间隔 B。但它们中的一些重叠。 (例如,DataFrame B 中每 10 分钟一次,DataFrame A 中每 5 分钟一次)。

如果 DataFrame A 中有 NaN 值,现在我想将温度数据从 DataFrame B 复制到 DataFrame A。

我有一个使用循环的方法,但它很慢。我想使用熊猫矢量化。但我不知道怎么做。谁能教教我?

    for i in tqdm(range(len(dfA['Temp']))):
       if(pd.isna(df['Temp'].iloc[i])):
         date_time_str = str(year) + '/' + str(month) + '/' + str(day)
         try:
            dfA['temp'].iloc[i] = float(dfB.loc[dfB['Date'] == date_time_str].iloc[:, 1])
            
         except:
            print("no value")
            pass

我的方案很慢,用pandas矢量化怎么办?

我尝试的矢量化方法:

dfA.loc[df['temp'].isnull() & ((datetime.datetime(dfA['Year'], df['*Month'], dfA['Day']).strftime("%Y/%m/%d %H:%M"))in dfB.Date.values) , 'temp'] = float(dfB[dfB['Date'] == datetime.datetime(dfA['Year'], df['*Month'], dfA['Day']].iloc[:, 1])

以上是我的方法,试过了,不行。

示例数据:

DataFrame A
Year    Month   Day Temperature
2020    1        17  25
2020    1        18  NaN
2020    1        19  28
2020    1        20  NaN
2020    1        21  NaN
2020    1        22  NaN

DataFrame B
Date    Temp
1/17/2020   25
1/19/2020   28
1/21/2020   31
1/23/2020   34
1/25/2020   23
1/27/2020   54

Expected Output
Year    Month   Day Temperature
2020    1        17 25
2020    1        18 NaN
2020    1        19 28
2020    1        20 NaN
2020    1        21 31
2020    1        22 NaN




【问题讨论】:

  • @Chirs,我添加了一些示例数据,请检查,谢谢
  • @Chris,我只是更改了示例数据,请检查,谢谢

标签: python pandas numpy vectorization


【解决方案1】:

使用pandas.to_datetimepandas.Series.fillna 的一种方式:

df1 = df1.set_index(pd.to_datetime(df1[["Year", "Month", "Day"]]))
s = df2.set_index(pd.to_datetime(df2.pop("Date"))).squeeze()
df1["Temperature"] = df1["Temperature"].fillna(s)
print(df1.reset_index(drop=True))

输出:

   Year  Month  Day  Temperature
0  2020      1   17         25.0
1  2020      1   18          NaN
2  2020      1   19         28.0
3  2020      1   20          NaN
4  2020      1   21         31.0
5  2020      1   22          NaN

【讨论】:

    【解决方案2】:

    让我们映射它们:

    dfa['Date']=pd.to_datetime(dfa[['Day','Month','Year']])
    dfb['Date']=pd.to_datetime(dfb['Date'])
    dfb['Temperature']=dfa.pop('Date').map(dfb.set_index('Date')['Temp'])
    

    让我们合并它们:

    dfa['Date']=pd.to_datetime(dfa[['Day','Month','Year']])
    dfb['Date']=pd.to_datetime(dfb['Date'])
    dfa=dfa.merge(dfb[['Date','Temp']],on='Date',how='left')
    dfa['Temperature']=dfa['Temperature'].fillna(dfa.pop('Temp'))
    

    【讨论】:

    • @Arurag Dabas,我发现应该是dfa.pop('Temp')。我想我只是犯了一个错误,所以我删除了评论。因为我们合并了 dfa 和 dfb。 dfa 现在有“temp”列。所以我们可以从 dfa['temp'] 中弹出值,然后将其写入 dfa['Temperature']。我不确定,你能帮我确认我的答案是正确的吗?非常感谢
    • @Stack 哦....然后更新了答案....是的,您是对的,因为我们将合并操作分配给 dfa 变量,所以它是dfa.pop('Temp') :)
    猜你喜欢
    • 1970-01-01
    • 2021-03-03
    • 2012-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-30
    • 2019-01-30
    • 2016-12-22
    相关资源
    最近更新 更多