Pandas isin()输出转字符串与代码优化求助:职场数据分析新手需求
Hey there! As someone who’s tackled similar data grouping tasks with Pandas before, let’s break this down step by step to get you a clean, efficient solution. I’ll cover adding grouping flags, converting isin() results to human-readable strings, and share practical optimization tips along the way.
1. 先明确数据结构(附示例数据)
First, let’s define sample DataFrames that match your scenario—this will make it easier to follow along. I’ll account for two common formats your grouping DataFrame might use:
示例1:分组DataFrame的Countries列是列表
import pandas as pd # 非洲国家指标主DataFrame africa_countries_df = pd.DataFrame({ "Country": ["Kenya", "Somalia", "South Africa", "Chad", "Nigeria"], "GDP": [98.2, 4.9, 419.9, 11.3, 477.3], "Population": [53.7, 15.8, 59.3, 16.8, 211.4] }) # 分组维度DataFrame(每组对应一个国家列表) country_groups_df = pd.DataFrame({ "Group": ["脆弱国家", "新兴经济体"], "Countries": [["Somalia", "Chad"], ["South Africa", "Nigeria"]] })
示例2:分组DataFrame的Countries列是逗号分隔字符串
If your grouping DataFrame stores countries as comma-separated strings (e.g., "Somalia,Chad"), first convert them to lists:
# 把逗号分隔字符串转成列表 country_groups_df["Countries"] = country_groups_df["Countries"].str.split(",")
2. 添加分组标记列
方法1:循环添加(直观适合新手)
If you only have a few groups, looping through each group to add a flag column is the most straightforward approach:
for _, row in country_groups_df.iterrows(): group_name = row["Group"] country_list = row["Countries"] # 先判断是否属于该组(布尔值),再转成"是"/"否"字符串 africa_countries_df[f"Is_{group_name}"] = africa_countries_df["Country"].isin(country_list).map({True: "是", False: "否"})
After running this, your africa_countries_df will have new columns like Is_脆弱国家 and Is_新兴经济体 with values "是" or "否".
方法2:向量式操作(更高效,适合大数据)
For large DataFrames, loops can be slow. Use vectorized operations and pd.concat to generate all flag columns at once:
# 生成每个分组的标记Series group_flags = [] for _, row in country_groups_df.iterrows(): flag_series = africa_countries_df["Country"].isin(row["Countries"]).map({True: "是", False: "否"}) flag_series.name = f"Is_{row['Group']}" group_flags.append(flag_series) # 合并标记列到原DataFrame africa_countries_df = pd.concat([africa_countries_df] + group_flags, axis=1)
3. isin()结果转字符串的细节
You mentioned converting isin() outputs to strings—we already used map() for this above. If you need custom string values (like "属于"/"不属于"), just adjust the mapping dictionary:
# 自定义映射规则 africa_countries_df["Is_脆弱国家"] = africa_countries_df["Country"].isin(fragile_countries).map({True: "属于", False: "不属于"})
Alternatively, use numpy.where() for more explicit logic:
import numpy as np africa_countries_df["Is_脆弱国家"] = np.where( africa_countries_df["Country"].isin(fragile_countries), "是", "否" )
4. 整体代码优化方案
优化点1:封装成函数,提升复用性
Wrap the entire logic in a function so you can reuse it for different datasets or groupings:
def add_group_flags(main_df, group_df, country_col="Country", group_col="Group", country_list_col="Countries", true_str="是", false_str="否"): """ 为主DataFrame添加分组标记列 参数: main_df: 包含国家指标的主DataFrame group_df: 包含分组信息的DataFrame country_col: 主DataFrame中国家列的名称 group_col: 分组DataFrame中分组名列的名称 country_list_col: 分组DataFrame中国家列表列的名称 true_str: 属于分组时的字符串值 false_str: 不属于分组时的字符串值 返回: 添加了标记列的主DataFrame """ group_flags = [] for _, row in group_df.iterrows(): flag_series = main_df[country_col].isin(row[country_list_col]).map({True: true_str, False: false_str}) flag_series.name = f"Is_{row[group_col]}" group_flags.append(flag_series) return pd.concat([main_df] + group_flags, axis=1) # 调用函数 africa_countries_df = add_group_flags(africa_countries_df, country_groups_df)
优化点2:处理重复数据
If your grouping DataFrame has duplicate countries or groups, clean it first to avoid redundant work:
# 对每组的国家列表去重 country_groups_df["Countries"] = country_groups_df["Countries"].apply(lambda x: list(set(x))) # 对分组名称去重(如果有重复分组) country_groups_df = country_groups_df.drop_duplicates(subset="Group")
优化点3:减少内存占用
Since flag columns only have 2 possible values, convert them to category type to save memory:
for col in africa_countries_df.columns: if col.startswith("Is_"): africa_countries_df[col] = africa_countries_df[col].astype("category")
优化点4:避免过度链式操作
While one-liners are concise, splitting logic into separate steps makes debugging easier. For example, instead of:
africa_countries_df[f"Is_{group_name}"] = africa_countries_df["Country"].isin(country_list).map({True: "是", False: "否"})
You could write:
is_in_group = africa_countries_df["Country"].isin(country_list) africa_countries_df[f"Is_{group_name}"] = is_in_group.map({True: "是", False: "否"})
最终效果示例
After running the code, your africa_countries_df will look like this:
| Country | GDP | Population | Is_脆弱国家 | Is_新兴经济体 |
|---|---|---|---|---|
| Kenya | 98.2 | 53.7 | 否 | 否 |
| Somalia | 4.9 | 15.8 | 是 | 否 |
| South Africa | 419.9 | 59.3 | 否 | 是 |
| Chad | 11.3 | 16.8 | 是 | 否 |
| Nigeria | 477.3 | 211.4 | 否 | 是 |
内容的提问来源于stack exchange,提问作者Tytire Recubans

