如何基于DataFrame的仓库与日期组合提取另一DataFrame的值
问题:从两个DataFrame中匹配提取对应值
现有两个DataFrame:df结构如下:
Warehouse Date Count 0 Delhivery Goa Warehouse 2022-05-12 83 1 Delhivery Goa Warehouse 2022-05-15 1 2 Delhivery Goa Warehouse 2022-05-18 100 3 Delhivery Tauru Warehouse 2022-05-19 100 4 Delhivery Tauru Warehouse 2022-05-20 100
df_orig结构如下:
index Goa Tauru 0 2022-05-12Delhivery Goa Warehouse 100.0 0.0 1 2022-05-15Delhivery Goa Warehouse 100.0 0.0 2 2022-05-18Delhivery Goa Warehouse 100.0 0.0 3 2022-05-20Delhivery Tauru Warehouse 0.0 50.0 4 2022-05-19Delhivery Tauru Warehouse 0.0 70.0
需要根据df的Warehouse与Date列的组合,从df_orig中提取对应值,预期输出:
Warehouse Date Count original 0 Delhivery Goa Warehouse 2022-05-12 83 100 1 Delhivery Goa Warehouse 2022-05-15 1 100 2 Delhivery Goa Warehouse 2022-05-18 100 100 3 Delhivery Tauru Warehouse 2022-05-19 100 70 4 Delhivery Tauru Warehouse 2022-05-20 100 50
用户初步尝试的代码:
df['index1'] = str(df['Date']) + str(df['Warehouse']) original = [] for index, row in df.iterrows(): if row['index1'] == df_orig['index']: original.append(????)
解决方案
问题分析
你之前的代码有两个关键问题:
str(df['Date'])会把整个Date列转成一个字符串(而非逐行取Date值),导致生成的index1完全错误,无法匹配df_orig的index列。row['index1'] == df_orig['index']是用标量和整个Series比较,得到的是布尔Series,不能直接用来判断匹配。
下面提供两种高效的实现方法:
方法一:使用apply逐行匹配(直观易懂)
import pandas as pd # 生成正确的匹配key:逐行拼接Date(转字符串)和Warehouse df['match_key'] = df['Date'].astype(str) + df['Warehouse'] # 将df_orig的index设为其"index"列,方便快速查找 df_orig.set_index('index', inplace=True) # 定义函数提取对应区域的值 def get_original_value(row): # 从Warehouse中提取区域(Goa/Tauru) region = row['Warehouse'].split()[1] # 根据match_key定位df_orig的行,再取对应区域列的值 return df_orig.loc[row['match_key'], region] # 生成original列 df['original'] = df.apply(get_original_value, axis=1) # 删除临时的match_key列(可选) df.drop('match_key', axis=1, inplace=True)
方法二:转长表后合并(向量化操作,效率更高)
适合数据量较大的场景,避免循环:
import pandas as pd # 将df_orig从宽表转成长表,每个index对应Goa/Tauru两行数据 df_orig_long = df_orig.melt( id_vars='index', var_name='Region', value_name='original' ) # 给df生成匹配key和提取Region列 df['match_key'] = df['Date'].astype(str) + df['Warehouse'] df['Region'] = df['Warehouse'].str.split().str[1] # 按match_key和Region合并两个DataFrame result = df.merge( df_orig_long, left_on=['match_key', 'Region'], right_on=['index', 'Region'], how='left' ).drop(columns=['match_key', 'index'])
两种方法都能得到预期的输出结果。
内容的提问来源于stack exchange,提问作者Rahul Sharma
相关产品推荐
相关产品推荐

