You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas新手求教:对比两DataFrame列并生成布尔标识列

简便实现跨DataFrame品牌信号区间匹配的方法

Hey there! 作为Pandas初学者,这种跨DataFrame的分组区间匹配需求其实有挺简洁的实现思路,我给你分享两种实用方法,你可以根据自己的场景选择:

方法一:合并后用自定义函数判断(逻辑直观,适合入门)

这种方法不需要复杂的数据结构转换,直接把两个DataFrame按Brand合并后,用自定义函数逐行判断信号所属区间,非常容易理解。

步骤示例:

  1. 首先准备你的数据(示例结构):
import pandas as pd

# 示例df1
df1 = pd.DataFrame({
    "Brand": ["A", "B"],
    "Signal_range": [
        {"Weak": [0, 30], "Average": [30, 70], "Strong": [70, 100]},
        {"Weak": [0, 25], "Average": [25, 75], "Strong": [75, 100]}
    ]
})

# 示例df2
df2 = pd.DataFrame({
    "order": [1, 2, 3],
    "Brand": ["A", "A", "B"],
    "signal": [25, 50, 80]
})
  1. 合并两个DataFrame,保留品牌对应的信号区间:
merged_df = df2.merge(df1[["Brand", "Signal_range"]], on="Brand", how="left")
  1. 定义判断函数,生成布尔标识列:
def judge_signal_interval(row):
    range_dict = row["Signal_range"]
    sig_val = row["signal"]
    # 根据区间规则判断(这里假设区间左闭右开,可根据实际调整)
    weak_flag = range_dict["Weak"][0] <= sig_val < range_dict["Weak"][1]
    average_flag = range_dict["Average"][0] <= sig_val < range_dict["Average"][1]
    strong_flag = range_dict["Strong"][0] <= sig_val < range_dict["Strong"][1]
    return pd.Series([weak_flag, average_flag, strong_flag], 
                     index=["weak_ind", "Average_ind", "Strong_ind"])

# 应用函数生成标识列
merged_df[["weak_ind", "Average_ind", "Strong_ind"]] = merged_df.apply(judge_signal_interval, axis=1)

# 可选:删除临时的Signal_range列
merged_df = merged_df.drop("Signal_range", axis=1)

执行后得到的结果就和你预期的示例一致啦:

order Brand  signal  weak_ind  Average_ind  Strong_ind
0      1     A      25      True        False       False
1      2     A      50     False         True       False
2      3     B      80     False        False        True

方法二:先展开区间列再用between(性能更优,适合大数据集)

如果你的数据量较大,apply逐行处理的性能会稍弱,这时可以先把df1的嵌套字典展开为区间上下限列,再用Pandas的between方法批量判断,速度更快。

步骤示例:

  1. 展开df1的Signal_range为区间上下限列:
# 把嵌套字典展开为多级索引列
df1_expanded = df1["Signal_range"].apply(pd.Series).applymap(lambda x: pd.Series(x, index=["low", "high"]))
df1_expanded.columns = pd.MultiIndex.from_product([["Weak", "Average", "Strong"], ["low", "high"]])

# 和原Brand列合并,得到处理后的df1
df1_processed = pd.concat([df1[["Brand"]], df1_expanded], axis=1)
  1. 合并df2和处理后的df1:
merged_df = df2.merge(df1_processed, on="Brand", how="left")
  1. 用between批量生成布尔列:
merged_df["weak_ind"] = merged_df["signal"].between(merged_df["Weak", "low"], merged_df["Weak", "high"], inclusive="left")
merged_df["Average_ind"] = merged_df["signal"].between(merged_df["Average", "low"], merged_df["Average", "high"], inclusive="left")
merged_df["Strong_ind"] = merged_df["signal"].between(merged_df["Strong", "low"], merged_df["Strong", "high"], inclusive="left")

# 可选:删除多余的区间列
merged_df = merged_df.drop([("Weak","low"), ("Weak","high"), ("Average","low"), ("Average","high"), ("Strong","low"), ("Strong","high")], axis=1)

这个方法利用了Pandas的向量化操作,比逐行apply效率高很多,适合处理大规模数据。

注意事项

  • 如果你的信号区间是闭区间(比如包含上限值),可以调整between的inclusive参数为"both",或者在自定义函数里把<改成<=。
  • 如果df2里有df1不存在的Brand,merge时用how="left"会保留这些行,对应的标识列会是NaN,你可以根据需求用fillna(False)处理。

内容的提问来源于stack exchange,提问作者JackJack

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:22:03