Python中使用Pandas筛选Excel中以M5/M6开头的行报错问题
高速公路关闭信息筛选问题解决
我是编程新手,正在编写一个查看特定高速公路计划关闭信息的Python程序。目前已实现按日期提取目标Excel工作表及指定列,但在筛选以"M5"或"M6"开头的行时,使用str.startswith("M6")和str.contains("M6")均出现报错。
原有代码
from datetime import datetime import pandas as pd url = 'https://nationalhighways.co.uk/media/s2pjwbuk/7-day-closure-report-26-july-web-upload.xls' dt = datetime.now() x = dt.weekday() column_name = [5] print(x) if x == 0: sheet_name = "Monday" data = pd.read_excel(url, sheet_name, usecols=column_name) print(data) if x == 1: sheet_name = "Tuesday" data = pd.read_excel(url, sheet_name, usecols=column_name) print(data) if x == 2: sheet_name = "Wednesday" data = pd.read_excel(url, sheet_name, usecols=column_name) print(data) if x == 3: sheet_name = "Thursday" data = pd.read_excel(url, sheet_name, usecols=column_name) print(data) if x == 4: sheet_name = "Friday" data = pd.read_excel(url, sheet_name, usecols=column_name) print(data) if x > 4: sheet_name = "Monday" data = pd.read_excel(url, sheet_name, usecols=column_name) print(data)
错误尝试分析
尝试写法1:
data = pd.read_excel(url, sheet_name, usecols=column_name.str.startwith("M6"))
错误原因:usecols参数仅用于指定要读取的列(位置或名称),不能在这里做行筛选,行筛选必须在数据读取完成后操作。尝试写法2:
print(data.str.contains"M6")
错误原因:data是DataFrame对象,没有直接的str属性,str方法属于pandas Series(单列数据),需要先提取目标列再调用。
修正后的代码
from datetime import datetime import pandas as pd url = 'https://nationalhighways.co.uk/media/s2pjwbuk/7-day-closure-report-26-july-web-upload.xls' dt = datetime.now() weekday_num = dt.weekday() # 用字典映射星期与工作表名,简化代码逻辑 weekday_sheet_map = { 0: "Monday", 1: "Tuesday", 2: "Wednesday", 3: "Thursday", 4: "Friday" } # 周末默认读取周一的工作表 sheet_name = weekday_sheet_map.get(weekday_num, "Monday") # 指定读取Excel第5列(1-based索引,对应E列) target_columns = [5] # 读取目标工作表与列 data = pd.read_excel(url, sheet_name=sheet_name, usecols=target_columns) print("原始数据:") print(data) # 筛选以"M5"或"M6"开头的行 # 提取唯一列,用startswith多前缀匹配,na=False忽略空值避免报错 filtered_data = data[data.iloc[:, 0].str.startswith(("M5", "M6"), na=False)] # 也可使用正则表达式实现相同筛选: # filtered_data = data[data.iloc[:, 0].str.contains(r'^M[56]', na=False)] print("\n筛选后的数据(M5/M6开头):") print(filtered_data)
关键说明
- 用字典替代多个
if判断,代码更简洁易维护; - 筛选时需先通过
data.iloc[:,0]提取目标列(因仅读取了一列,索引为0),再调用str方法; str.startswith(("M5", "M6"))支持传入元组实现多前缀匹配;na=False用于处理空值,避免因空值无法调用str方法而报错;- 正则表达式
^M[56]也可实现相同筛选,^表示匹配字符串开头,[56]匹配5或6。
内容的提问来源于stack exchange,提问作者3k1m
相关产品推荐
相关产品推荐

