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

如何在Pandas中拆分DataFrame、处理并合并?索引分组拓展特征方法

当然有!在Pandas里处理这种「按索引/分组键拆分数据、计算新特征再合并回原结构」的需求,有好几套顺手的方案,完全不用手动拆分组再拼接,我结合你的NYC GreenTaxi场景给你捋捋~

方法1:用groupby().transform()(最推荐,适合单特征广播回原行)

如果你的预定义函数是对每个分组计算单个值(比如每个上车点ID对应的行政区名称),然后要把这个值对应到原DataFrame的每一行,transform绝对是最优解——它会自动把分组计算的结果扩展成和原数据一样的长度,直接新增列就行,完全不用操心合并的事儿。

举个贴合你场景的例子:

import pandas as pd
from geopy.geocoders import Nominatim

# 定义你的地址查询函数(这里简化逻辑,实际替换成真实的geopy查询)
def get_neighborhood(location_id):
    geolocator = Nominatim(user_agent="green_taxi_geo_app")
    # 假设你有location_id和经纬度的映射,或者直接查询(注意API调用限制)
    # 这里返回模拟结果,实际替换成真实查询逻辑
    return f"Brooklyn Area {location_id}"

# 加载GreenTaxi数据(假设你已经下载好)
df = pd.read_parquet("./green_tripdata_2023-01.parquet")

# 一行代码生成新特征!
df["pickup_neighborhood"] = df.groupby("PULocationID")["PULocationID"].transform(get_neighborhood)

这里groupby("PULocationID")按上车地点ID分组,transform(get_neighborhood)会对每个分组的ID应用函数,然后自动把结果匹配回原DataFrame的每一行,索引完全对应,省心到爆。

方法2:用groupby().apply() + 自动合并(适合返回多特征/复杂结果)

如果你的函数需要对整个分组的DataFrame做处理,返回带多个新特征的分组数据(比如每个上车点返回行政区、邮编、区域类型),那用apply就很合适——Pandas会自动把所有处理后的分组拼接回原结构。

例子:

def process_location_group(group_df):
    # 获取当前分组的上车点ID
    loc_id = group_df["PULocationID"].iloc[0]
    geolocator = Nominatim(user_agent="green_taxi_geo_app")
    
    # 模拟查询得到多维度信息
    neighborhood = f"Queens Area {loc_id}"
    zip_code = f"113{loc_id % 100}"
    area_type = "Residential" if loc_id < 100 else "Commercial"
    
    # 给当前分组添加新列
    group_df["pickup_neighborhood"] = neighborhood
    group_df["pickup_zip"] = zip_code
    group_df["pickup_area_type"] = area_type
    return group_df

# 应用函数,自动合并回原结构
processed_df = df.groupby("PULocationID", group_keys=False).apply(process_location_group)

# processed_df就是带新特征的完整数据,索引和原数据完全一致,直接用就行!

加个group_keys=False是为了避免生成多余的分组键列,让结果更干净。

方法3:预计算映射表 + map()(适合耗时的API/数据库查询)

如果你的函数调用比较耗时(比如geopy的API查询,频繁调用容易被限流或者变慢),那最好先预计算所有唯一分组键的结果,再用map映射到原数据——这样能减少重复调用次数,效率提升一大截。

例子:

# 先提取所有唯一的上车点ID
unique_pu_ids = df["PULocationID"].unique()

# 预计算每个ID对应的结果,存在字典里
location_info_map = {}
geolocator = Nominatim(user_agent="green_taxi_geo_app")

for loc_id in unique_pu_ids:
    # 实际查询逻辑(记得加超时、缓存哦)
    location_info_map[loc_id] = {
        "neighborhood": f"Bronx Area {loc_id}",
        "zip_code": f"104{loc_id % 100}"
    }

# 用map快速生成新列
df["pickup_neighborhood"] = df["PULocationID"].map(lambda x: location_info_map[x]["neighborhood"])
df["pickup_zip"] = df["PULocationID"].map(lambda x: location_info_map[x]["zip_code"])

这种方法特别适合需要外部调用的场景,比如查地理信息、查数据库,只需要查询一次每个唯一值,比分组后每次调用函数高效太多。

小提醒

  • 如果你的函数需要用到分组里的多列数据,transform也支持,比如计算每个上车点的平均行程时间,然后加到每一行:df["avg_pu_trip_time"] = df.groupby("PULocationID")["trip_duration"].transform("mean")
  • 用geopy的时候,记得设置timeout参数,避免请求超时,也可以用functools.lru_cache缓存查询结果,进一步减少重复请求。

内容的提问来源于stack exchange,提问作者Sandeep R Venkatesh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:38:03