如何将pd.merge数据合并代码改为pd.concat,适配datetime64[ns]弃用?
用pd.concat替代pd.merge实现DataFrame合并的方法
首先得明确:pd.merge是按指定列匹配关联后合并(类似数据库的JOIN逻辑),而pd.concat是直接按行或列堆叠,两者核心逻辑完全不同。直接替换会导致数据错位,必须先手动将所有DataFrame的行对齐,再用pd.concat拼接。
针对你的代码,原逻辑是先通过Date和Time关联ads_hour与ads,再通过Time和TV关联结果与advertising,以下是改用pd.concat的实现:
# 转换日期时间列(保留原逻辑) ads_hour['Date'] = pd.to_datetime(ads_hour['Date'], errors='coerce') ads['Time'] = pd.to_datetime(ads['Time'], errors='coerce') # 第一步:先获取原merge逻辑下的基准匹配行(确保所有DataFrame的行一致) # 先关联ads_hour和ads,得到匹配的中间数据集 temp = pd.merge(ads_hour, ads, left_on='Date', right_on='Time', how='inner') # 再关联得到最终匹配的基准数据,用于后续筛选原始DataFrame base_data = pd.merge(temp, advertising, left_on='Time', right_on='TV', how='inner') # 第二步:筛选每个原始DataFrame,只保留和基准数据匹配的行,并重置索引保证对齐 # 筛选ads_hour ads_hour_filtered = ads_hour[ads_hour['Date'].isin(base_data['Date'])].reset_index(drop=True) # 筛选ads ads_filtered = ads[ads['Time'].isin(base_data['Time'])].reset_index(drop=True) # 筛选advertising advertising_filtered = advertising[advertising['TV'].isin(base_data['TV'])].reset_index(drop=True) # 第三步:用pd.concat横向拼接列(axis=1表示按列拼接) allData = pd.concat([ads_hour_filtered, ads_filtered, advertising_filtered], axis=1) # 移除重复列(拼接后会重复出现Date/Time/TV这类关联列) allData = allData.loc[:, ~allData.columns.duplicated()] # 展示结果 print(allData.head())
关键说明:
pd.concat本身不做关联匹配,所以必须先通过筛选保证所有要拼接的DataFrame行数相同、行顺序完全一致,否则会出现数据错位- 代码中
how='inner'对应原merge的默认逻辑,如果原代码用了left/right/outer类型的关联,需要调整基准数据的生成逻辑(比如用对应类型的join结果作为筛选基准) - 最后去重列是可选操作,按需保留重复的关联列即可
内容的提问来源于stack exchange,提问作者Migs Panganiban
相关产品推荐
相关产品推荐

