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

如何筛选DataFrame指定列值为英文的行并解决langdetect报错?

问题描述

我有一个包含27列的DataFrame,其中包含FonctionsStagiaire和ExigencesParticulieres两列,共13774行,内容均为英文或法文。我希望仅保留这两列值均为英文的行,删除列值为法文的整行。

使用langdetect库时遇到错误:

langdetect.lang_detect_exception.LangDetectException: No features in text.

试过Stack Overflow上的各种方案都没用,现在发现每行都会触发这个错误。另外还需要处理这两列里仅含NaN、数字、空格或标点这类没法检测语言的内容。

我优先想用langdetect,其他有效方案也可以接受,以下是我尝试的代码:

from langdetect import detect
import pandas as pd
import re
import string

def filter_nonenglish(df):
     
    list = ['FonctionsStagiaire', 'ExigencesParticulieres']

    for col in list:       
        #to check if values are only whitespaces or only numeric characters or only punctuation marks
        #something like this -> if (df[col].apply(lambda x: x.isnumeric()) == True) | (df[col].apply(lambda x: x.isspace()) == True) | (all(i in string.punctuation for i in df[col]) == True):
            return False     
        else:
            #trying to use apply() to apply detect() to each <str> values of the columns and not to the entire pd.Series object
            new_df = df[(df[col].apply(detect).eq('en'))]

    return new_df
   
    #df['FonctionsStagiaire'] = df['FonctionsStagiaire'].apply(detect)
    #df['ExigencesParticulieres'] = df['ExigencesParticulieres'].apply(detect)
    
    #df = df[df['FonctionsStagiaire'] == 'en']
    #df = df[df['ExigencesParticulieres'] == 'en']
    
    #new_df = df[(df.FonctionsStagiaire.apply(detect).eq('en')) & (df.ExigencesParticulieres.apply(detect).eq('en'))]
    
df = pd.read_csv('emplois_df_parsed.csv')

df = df[df['FonctionsStagiaire'].notna() & df['ExigencesParticulieres'].notna()]   #to remove empty values

#to check whether all empty values are removed or not in the column 'FonctionsStagiaire'
#df['FonctionsStagiaire'] = df['FonctionsStagiaire'].str.lower()  
#df = df[df['FonctionsStagiaire'].str.islower()]

#to check whether all empty values are removed or not in the column 'ExigencesParticulieres'
#df['ExigencesParticulieres'] = df['ExigencesParticulieres'].str.lower()
#df = df[df['ExigencesParticulieres'].str.islower()]

#to make sure that values of both the columns are of <str> datatype
df['FonctionsStagiaire'] = pd.Series(df['FonctionsStagiaire'], dtype = "string")
df['ExigencesParticulieres'] = pd.Series(df['ExigencesParticulieres'], dtype = "string")

#bool(re.match('^(?=.*[a-zA-Z])', df.loc[:, 'FonctionsStagiaire']))
#bool(re.match('^(?=.*[a-zA-Z])', df.loc[:, 'ExigencesParticulieres']))

#   df[df[column].map(lambda x: x.isascii())]

df_new = filter_nonenglish(df)

df_new.to_csv('emplois_df_filtered.csv', index= False)

解决方案

问题根源

  1. langdetect.detect()无法处理仅含数字、空格、标点的字符串,这类内容没有语言特征,直接触发No features in text异常
  2. 你的filter_nonenglish函数逻辑错误:循环里直接return False会提前终止函数,而且没有同时筛选两列,最终只处理了最后一列

修复后的langdetect方案

先预处理过滤无效文本,再封装安全的检测函数,最后同时筛选两列均为英文的行:

from langdetect import detect, LangDetectException
import pandas as pd
import re

def has_valid_text(text):
    """判断文本是否包含有效字母(排除仅数字、空格、标点的情况)"""
    if pd.isna(text):
        return False
    # 匹配至少一个大小写字母
    return bool(re.search(r'[a-zA-Z]', str(text)))

def safe_detect(text):
    """安全检测语言,捕获异常返回None"""
    if not has_valid_text(text):
        return None
    try:
        return detect(text)
    except LangDetectException:
        return None

def filter_english_only(df):
    target_cols = ['FonctionsStagiaire', 'ExigencesParticulieres']
    
    # 先过滤掉两列都无有效文本的行
    df = df[df[target_cols].applymap(has_valid_text).any(axis=1)]
    
    # 为每列添加语言检测结果列
    for col in target_cols:
        df[f'{col}_lang'] = df[col].apply(safe_detect)
    
    # 保留两列均检测为英文的行
    result_df = df[(df['FonctionsStagiaire_lang'] == 'en') & (df['ExigencesParticulieres_lang'] == 'en')]
    
    # 移除临时语言列
    result_df = result_df.drop(columns=[f'{col}_lang' for col in target_cols])
    
    return result_df

# 读取数据
df = pd.read_csv('emplois_df_parsed.csv')

# 移除两列均为NaN的行
df = df[df['FonctionsStagiaire'].notna() & df['ExigencesParticulieres'].notna()]

# 统一转换为字符串类型
df['FonctionsStagiaire'] = df['FonctionsStagiaire'].astype(str)
df['ExigencesParticulieres'] = df['ExigencesParticulieres'].astype(str)

# 执行筛选
df_new = filter_english_only(df)

# 保存结果
df_new.to_csv('emplois_df_filtered.csv', index=False)

代码说明

  • has_valid_text:用正则快速过滤掉无有效字母的内容,避免无效检测
  • safe_detect:封装检测函数,捕获异常防止崩溃,无效内容返回None
  • filter_english_only:先清理无效行,再检测语言,最后严格筛选两列都是英文的行

替代方案:使用langid库

如果langdetect还是不稳定,可以试试langid,它对短文本的兼容性更好:

先安装:

pip install langid

替换safe_detect函数:

import langid

def safe_detect(text):
    if not has_valid_text(text):
        return None
    try:
        lang, _ = langid.classify(text)
        return lang
    except:
        return None

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 18:12:49