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

Pandas如何通过apply调用自定义函数基于单列生成多列

Pandas 映射类方法区别

先明确三个易混淆方法的适用场景:

  • map:仅支持Series对象,对单列逐元素做单值映射,输入单个元素返回单个结果,无法直接生成多列
  • apply:兼容Series和DataFrame对象:作用在Series上时逐元素运算,支持返回元组/列表形式的多结果;作用在DataFrame上时可指定按行/按列做聚合计算,是当前单列派生多列场景的适配方法
  • applymap:仅支持DataFrame对象,对整个表的所有单元格逐元素做统一处理,适合全表元素的格式转换类操作,不适合单列派生多列的需求
多返回值派生多列实现

你的原有爬取函数不需要做任何修改,直接通过如下写法即可在原表基础上新增3列对应爬取结果:

# 直接对url列执行apply,将返回的元组序列转为列表后赋值给新列
df[['row4', 'row5', 'row6']] = df['url'].apply(get_stuff_from_url).tolist()

逻辑说明:

  • 不需要额外套lambda表达式,apply会自动将url列的每个字符串传入爬取函数,此时得到的是每行存储一个三元组的Series对象
  • 调用.tolist()后会将三元组序列拆为[(data1,data2,data3), ...]格式的嵌套列表,pandas会自动按顺序将三个值匹配到你指定的三个新列中,原有列会完整保留,不需要额外做表合并操作

爬取场景优化建议

网页爬取存在网络波动、页面结构变动的可能,建议给爬取函数增加异常捕获和空值判断,避免单个url请求失败导致整个计算流程中断:

import time
import requests
from bs4 import BeautifulSoup

def get_stuff_from_url(url: str, retry=2):
    for i in range(retry+1):
        try:
            # 增加超时设置和请求头,避免请求卡死或被反爬拦截
            resp = requests.get(url, timeout=10, headers={"User-Agent": "Mozilla/5.0"})
            resp.raise_for_status()
            soup = BeautifulSoup(resp.text, "html.parser")
            # 增加标签存在性判断,避免页面结构变动时取text报错
            data1 = soup.find('div', {'class': 'stuff1'})
            data2 = soup.find('span', {'class': 'stuff2'}).text if soup.find('span', {'class': 'stuff2'}) else None
            data3 = soup.find('p', {'class': 'stuff3'}).text if soup.find('p', {'class': 'stuff3'}) else None
            return data1, data2, data3
        except Exception as e:
            if i == retry:
                print(f"url {url} 爬取失败,错误信息:{str(e)}")
                return None, None, None
            time.sleep(1) # 失败后重试间隔1秒

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 23:33:29