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

Pandas SettingWithCopyWarning及Too many indexers错误解决求助

问题:Pandas SettingWithCopyWarning及.loc索引错误解决

发送请求抓取网页文本时遇到以下警告,尝试使用.copy()无效,改用_df.loc时又触发too many indexers错误:

SettingWithCopyWarning:
A value is trying to be set on a copy of a
slice from a DataFrame

See the caveats in the documentation:
https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy _df['text']=remove_one_words_from_list(website_text,_df['language']).copy()

注:调用get_the_text2方法时,每次传入DataFrame的一行数据。

相关代码

def get_the_text2(_df):
    '''
    第二次用不同方法发送请求,获取文章文本
    参数
    ----------
    _df : DataFrame
    
    返回
    -------
    URL对应的文本内容
    '''  
    df['text']=''
    # for k,i in enumerate(_df['url']):
    if str(_df):
          website_text=list()
          print(_df)   
          #time.sleep(2)
          try:
            response=requests.get(_df['url'],headers={"User-Agent" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36"})              
            status_code=response.status_code
            soup = BeautifulSoup(response.content, 'html.parser')
            
            if len(website_text)<=10:
                        website_text=list()
                        if soup.article:
                            if soup.article.find_all(['p',re.compile("^h\d{1}")]):   
                                for data in soup.article.find_all(['p',re.compile("^h\d{1}")]):                          
                                    website_text.append(data.get_text(strip=True))            
                                #df.at[k,'text']=remove_one_words_from_list(website_text,df.at[k,'language'])
                                _df['text']=remove_one_words_from_list(website_text,_df['language']).copy()
                                print('****ARTICLE P & H{1}****',remove_one_words_from_list(website_text,_df['language']))

for _index,item in enumerate(df['status_code']):
  if item !=200:
    get_the_text2(df.loc[_index])

编辑1:.loc索引报错信息

使用以下代码时:

_df['text']=remove_one_words_from_list(website_text,_df.loc[:,'language']).copy()

触发报错:

IndexingError                             Traceback (most recent call last)
Cell In[14], line 102
    100 for _index,item in enumerate(df['status_code']):
    101   if item !=200:
--> 102     get_the_text2(df.loc[_index])

File c:\Users\\anaconda3\envs\GDELT\Lib\site-packages\pandas\core\indexing.py:939, in _LocationIndexer._validate_key_length(self, key)
    937             raise IndexingError(_one_ellipsis_message)
    938         return self._validate_key_length(key)
--> 939     raise IndexingError("Too many indexers")
    940 return key

IndexingError: Too many indexers

编辑2:.loc['language']无报错但警告仍存在

改用以下代码后无索引错误,但SettingWithCopyWarning依旧:

_df['text']=remove_one_words_from_list(website_text,_df.loc['language']).copy()

已知问题根源,但不清楚具体修复方法。


解决方案

  1. 问题本质:传入get_the_text2的df.loc[_index]是Series对象,不是DataFrame。直接对Series赋值会触发视图/副本歧义警告;而_df.loc[:,'language']是给Series用了二维索引语法,因此报错。

  2. 修复代码示例:

def get_the_text2(df, idx):
    '''
    第二次用不同方法发送请求,获取文章文本并更新到原DataFrame
    参数
    ----------
    df : DataFrame
        原数据集
    idx : int
        需要处理的行索引
    '''  
    url = df.loc[idx, 'url']
    language = df.loc[idx, 'language']
    website_text = []
    
    try:
        response = requests.get(url, headers={"User-Agent" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36"})              
        soup = BeautifulSoup(response.content, 'html.parser')
        
        if soup.article:
            # 提取所有p和h标签文本
            for data in soup.article.find_all(['p', re.compile("^h\d{1}")]):                          
                website_text.append(data.get_text(strip=True))            
            # 用.at精准赋值,彻底避免视图/副本问题
            processed_text = remove_one_words_from_list(website_text, language)
            df.at[idx, 'text'] = processed_text
            print('****ARTICLE P & H{1}****', processed_text)
    except Exception as e:
        print(f"处理索引{idx}时出错: {e}")
        df.at[idx, 'text'] = ''

# 修改调用逻辑,直接传递索引和原DataFrame
for idx, status in df['status_code'].items():
    if status != 200:
        get_the_text2(df, idx)
  1. 修复逻辑说明:
  • 直接操作原DataFrame,避免传递单行Series导致的副本歧义
  • 使用.at[idx, 'text']精准定位赋值,完全符合Pandas安全索引规范,消除SettingWithCopyWarning
  • 移除函数内不必要的全局赋值df['text']='',避免污染原数据集

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 09:14:59