【问题标题】:Applying lambda function to pandas dataframe - returns index but not values?将 lambda 函数应用于 pandas 数据框 - 返回索引但不返回值?
【发布时间】:2019-01-17 22:40:39
【问题描述】:

我正在运行一个进程来清理一些电话号码(英国),并决定使用正则表达式/替换在 Pandas DataFrame 中运行一个 lambda 函数来删除我不想包含的字符(非数字,允许一个+)

代码如下:(phone_test只是一个测试示例的DataFrame,两列,一个索引和值)

def clean_phone_number(tel_no):
    for row in test_data:
        row = re.sub('[^?0-9+]+', '', row)
        return(row)

phone_test_result = phone_test['TEL_NUMBER'].apply(lambda x: clean_phone_number(x))

我遇到的问题是结果 (phone_test_result) 只返回 phone_test 数据帧的索引,而不是新格式化的电话号码。我已经绞尽脑汁好几个小时了,但我确信这是一个简单的问题。

起初我以为这只是返回线的定位(它应该在 for 下方,对吗?)但是当我这样做时,我只得到一个电话号码的输出,重复循环的长度(这甚至不在 phone_test 数据帧中!)

请停止。 谢谢。


在回复之后,这就是我最终得到的结果:

使用正则表达式清理电话号码,只取前 13 个字符
- 用 +44 替换前导零
- 删除长度小于 13 个字符的所有内容。
这并不完美;
- 有一些电话号码的合法数字较少
- 意味着我删除了所有的分机号码

def clean_phone_number(tel_no):
    clean_tel = re.sub('[^?0-9+]+', '', tel_no)[:13]
    if clean_tel[:1] == '0':
        clean_tel = '+44'+clean_tel[1:]
        if len(clean_tel) < 13:
            clean_tel = ''
    return(clean_tel)

【问题讨论】:

    标签: python python-3.x pandas lambda


    【解决方案1】:

    pd.Series.apply 将函数应用于系列中的每个。注意lambda 是不必要的。

    import re
    
    phone_test = pd.DataFrame({'TEL_NUMBER': ['+44-020841396', '+44-07721-051-851']})
    
    def clean_phone_number(tel_no):
         return re.sub('[^?0-9+]+', '', tel_no)
    
    phone_test_result = phone_test['TEL_NUMBER'].apply(clean_phone_number)
    
    # 0      +44020841396
    # 1    +4407721051851
    # Name: TEL_NUMBER, dtype: object
    
    相比之下,

    pd.DataFrame.apply 将函数应用于数据帧中的每个

    def clean_phone_number(row):
         return re.sub('[^?0-9+]+', '', row['TEL_NUMBER'])
    
    phone_test_result = phone_test.apply(clean_phone_number, axis=1)
    
    # 0      +44020841396
    # 1    +4407721051851
    # Name: TEL_NUMBER, dtype: object
    

    【讨论】:

      【解决方案2】:

      你不必循环,函数会针对每个元素执行

      def clean_phone_number(tel_no):
          return re.sub('[^?0-9+]+', '', tel_no)
      

      或直接

      phone_test_result = phone_test['TEL_NUMBER'].apply(lambda x: re.sub('[^?0-9+]+', '', x))
      

      【讨论】:

      • You don't have to loop。澄清一下,apply 只是一个隐蔽的循环。
      • 是的,从某种意义上说“不需要编写自己的 for 循环”,但如果 OP 没有意识到这一点,最好在这里澄清一下:)
      • 非常感谢您的澄清-我已经全职编写python一个月了,并且一直在我打算与apply一起使用的函数中包含循环......不断!!跨度>
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-11-26
      • 1970-01-01
      • 1970-01-01
      • 2022-01-16
      • 2020-11-20
      • 2019-09-05
      • 2018-07-26
      相关资源
      最近更新 更多