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

Python中对DataFrame应用函数触发ValueError的解决方法

问题原因分析

你遇到的ValueError核心原因是:apply是逐行传递单个手机号值给函数,但你的vanity_def函数却一直在操作整个DataFrame的列。

vanity_class.MNM_MOBILE_NUMBER.astype(str).str.match(...)返回的是一个布尔Series,而if语句无法直接判断Series的真假(pandas不知道你要判断any()还是all()),因此抛出"真值歧义"的错误。同时,函数里直接修改整个DataFrame列的逻辑也是错误的——apply不需要你全局赋值,只需要返回当前行的分类结果即可。

修正方案

1. 核心调整方向

  • 函数接收单个手机号值,先转为字符串
  • 使用Python标准库re对单个字符串做正则匹配
  • 函数仅返回当前手机号对应的分类标签,不全局修改DataFrame

2. 修正后的完整代码

import pandas as pd
import re

# 创建原始DataFrame
numbers = [539249751,530246444,539246655,539209759,538849098]
vanity_class = pd.DataFrame(numbers, columns=['MNM_MOBILE_NUMBER'])

# 重写分类函数
def vanity_def(mobile_num):
    num_str = str(mobile_num)
    
    # Diamond 分类规则
    diamond_patterns = [
        r'^5(\d)\1{7}',
        r'^5(?!(\d)\1)\d(\d)\2{6}$',
        r'.{2}(?!(\d)\1)\d(\d)\2{5}$',
        r'^\d*(\d)(\d)(?:\1\2){3}\d*$',
        r'^5((\d)\2{3})((\d)\4{3})$',
        r'.{3}(1234567$)'
    ]
    if any(re.match(p, num_str) for p in diamond_patterns):
        return 'Diamond'
    
    # Gold 分类规则
    gold_patterns = [
        r'.{3}(?!(\d)\1)\d(\d)\2{4}$',
        r'^(?!(\d)\1)\d((\d)\3{6})(?!\3)\d$',
        r'\d(\d)\1(\d)\2(\d)\3(\d)\4'
    ]
    if any(re.match(p, num_str) for p in gold_patterns):
        return 'Gold'
    
    # Silver 分类规则
    silver_patterns = [
        r"^5(?!(\d)\1)\d((\d)\3{5})(?!\3)\d",
        r"\b\d\d(\d)(?!\1)(\d)\2\2(\d)\3\3\b"
    ]
    if any(re.match(p, num_str) for p in silver_patterns):
        return 'Silver'
    
    # Bronze 分类规则
    bronze_patterns = [
        r'.{3}(123456$)',
        r'^5.{3}(?!(\d)\1)\d(\d)\2{3}$',
        r'\d\d(?!(\d)\1)\d((\d)\3{4})(?!\3)\d',
        r'\b\d\d(\d)(\d(00))\2',
        r'^5(\d(000))(\d(000))'
    ]
    if any(re.match(p, num_str) for p in bronze_patterns):
        return 'Bronze'
    
    # Special 分类规则
    special_patterns = [
        r"\d\d(?!(\d)\1)\d((\d)\3{3})(?!\3)\d",
        r"\d\d\d(\d\d)(?!\1)(\d)\2(\d)\3\b",
        r"^\d*(\d)(\d)(?:\1\2){2}\d*$"
    ]
    if any(re.match(p, num_str) for p in special_patterns):
        return 'Special'
    
    # Economy 分类规则
    economy_patterns = [
        r'.{4}(45678$)',
        r'.{5}(?!(\d)\1)\d(\d){3}',
        r'.{5}(1234$)',
        r'(?!.*(\d)\1(\d)\2(\d)\3).{4}\d(\d)\4(\d)\5',
        r'^\d*(\d)(\d)(?:\1\2){1}\d*$'
    ]
    if any(re.match(p, num_str) for p in economy_patterns):
        return 'Economy'
    
    return 'Non Classified'

# 应用函数生成新列
vanity_class['MNC_New_Class'] = vanity_class['MNM_MOBILE_NUMBER'].apply(vanity_def)

3. 关键优化点

  • 把同分类的正则整理成列表,用any()实现"或"逻辑,和你原代码的|效果一致
  • 使用re.match和pandas的str.match行为对齐(从字符串开头匹配),如果需要任意位置匹配,可替换为re.search
  • 函数仅返回当前行的结果,由apply自动组合成新列,避免全局修改DataFrame的错误逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 11:20:37