Python重构维基百科皮克斯电影列表表格遇问题求助
问题
我是Python初学者,正在重构维基百科《皮克斯电影列表》的表格,跟着YouTube视频操作时卡壳了。我的需求是:
- 移除“编剧”板块双层表头中的
Writers单元格,仅保留Story和Screenplay作为独立表头列 - 删除最后两个无关的表头列(
Elio、Inside Out 2)
操作后出现如下ValueError,提示列数与行数据长度不匹配:
ValueError Traceback (most recent call last) Cell In[16], line 6 3 individual_row_data = [data.text.strip() for data in row_data] 5 length = len(df) ----> 6 df.loc[length] = individual_row_data File ~/anaconda3/lib/python3.11/site-packages/pandas/core/indexing.py:818, in _LocationIndexer.__setitem__(self, key, value) 815 self._has_valid_setitem_indexer(key) 817 iloc = self if self.name == "iloc" else self.obj.iloc ---> 818 iloc._setitem_with_indexer(indexer, value, self.name) File ~/anaconda3/lib/python3.11/site-packages/pandas/core/indexing.py:1785, in _iLocIndexer._setitem_with_indexer(self, indexer, value, name) 1782 indexer, missing = convert_missing_indexer(indexer) 1784 if missing: -> 1785 self._setitem_with_indexer_missing(indexer, value) 1786 return 1788 if name == "loc": 1789 # must come after setting of missing File ~/anaconda3/lib/python3.11/site-packages/pandas/core/indexing.py:2160, in _iLocIndexer._setitem_with_indexer_missing(self, indexer, value) 2157 if is_list_like_indexer(value): 2158 # must have conforming columns 2159 if len(value) != len(self.obj.columns): -> 2160 raise ValueError("cannot set a row with mismatched columns") 2162 value = Series(value, index=self.obj.columns, name=indexer) 2164 if not len(self.obj): 2165 # We will ignore the existing dtypes instead of using 2166 # internals.concat logic ValueError: cannot set a row with mismatched columns
我可以提供相关文件,求帮助或指导。
原因分析
这个错误的核心是修改后的DataFrame列数,和提取的每行数据长度不匹配:
- 维基百科的表格是双层合并表头,移除
Writers并拆分出Story/Screenplay、删除最后两列后,DataFrame列数已变化,但提取行数据的逻辑没同步调整,导致每行数据长度和列数对不上 - 手动遍历HTML行时,可能还在提取对应
Elio/Inside Out 2的空值或占位内容,或者没正确拆分Writers对应的两个子列数据,导致长度偏差
解决方法
方法1:用pandas直接处理多层表头(更省心,避免手动遍历)
不用手动爬取每行,直接用pandas.read_html解析维基表格的双层表头,再调整列名和删除无关列:
import pandas as pd # 读取维基表格,指定双层表头(第0行和第1行作为表头) dfs = pd.read_html("https://en.wikipedia.org/wiki/List_of_Pixar_films", header=[0, 1]) # 目标表格是第一个DataFrame(根据实际情况调整索引) df = dfs[0] # 重构列名:拆分Writers的子列,跳过要删除的列 new_cols = [] for col_tuple in df.columns: main_col, sub_col = col_tuple # 处理Writers的子列 if main_col == "Writers": new_cols.append(sub_col) # 跳过要删除的列 elif main_col in ["Elio", "Inside Out 2"]: continue # 其他列直接用主列名 else: new_cols.append(main_col) # 重新设置列名,并删除无关列 df.columns = new_cols df = df.drop(columns=["Elio", "Inside Out 2"], errors="ignore") # 查看结果 print(df.columns)
方法2:调整手动提取行数据的逻辑
如果坚持手动遍历HTML行,要确保提取的每行数据长度和修改后的DataFrame列数一致:
# 假设你已经获取了修改后的DataFrame df individual_row_data = [data.text.strip() for data in row_data] # 1. 跳过最后两个无关列的数据 individual_row_data = individual_row_data[:-2] # 2. 检查长度是否匹配(调试用) if len(individual_row_data) != len(df.columns): print(f"数据长度:{len(individual_row_data)},列数:{len(df.columns)}") print("行数据内容:", individual_row_data) print("DataFrame列名:", df.columns.tolist()) else: # 长度匹配再添加行 df.loc[len(df)] = individual_row_data
调试时重点看:individual_row_data里是不是多了/少了元素,比如有没有把Writers对应的两个子列数据都保留,有没有删掉最后两个无关列的内容。
内容的提问来源于stack exchange,提问作者tslusk
相关产品推荐
相关产品推荐

