解决DataFrame无str属性错误:extractall函数使用问题
错误原因与解决方法
核心问题
你代码里的df是DataFrame对象,但str属性是pandas Series(单列数据)的专属属性,DataFrame本身没有这个属性,所以调用df.str.extractall必然会报AttributeError。
解决步骤
- 指定目标列:先确定你要处理的日期文本存在DataFrame的哪一列,比如假设列名叫
date_content(你需要换成自己实际的列名)。所有正则提取操作都要针对这一列,而非整个DataFrame。 - 替换所有
df为目标列:把代码中所有的df.str.extractall替换成df['date_content'].str.extractall,包括带索引筛选的df[index_left].str.extractall要改成df['date_content'][index_left].str.extractall。 - (可选)优化代码结构:尽量不要用
global df,改成把DataFrame作为参数传入函数,避免全局变量带来的潜在问题。
修改后的示例代码
import pandas as pd def date_sorter(df, target_col='date_content'): # 目标列转为Series date_series = df[target_col] # Full date dates_extracted = date_series.str.extractall(r'(?P<origin>(?P<month>\d?\d)[/|-](?P<day>\d?\d)[/|-](?P<year>\d{4}))') index_left = ~date_series.index.isin([x[0] for x in dates_extracted.index]) dates_extracted = dates_extracted.append(date_series[index_left].str.extractall(r'(?P<origin>(?P<month>\d?\d)[/|-](?P<day>([0-2]?[0-9])|([3][01]))[/|-](?P<year>\d{2}))')) index_left = ~date_series.index.isin([x[0] for x in dates_extracted.index]) del dates_extracted[3] del dates_extracted[4] dates_extracted = dates_extracted.append(date_series[index_left].str.extractall(r'(?P<origin>(?P<day>\d?\d) ?(?P<month>[a-zA-Z]{3,})\.?,? (?P<year>\d{4}))')) index_left = ~date_series.index.isin([x[0] for x in dates_extracted.index]) dates_extracted = dates_extracted.append(date_series[index_left].str.extractall(r'(?P<origin>(?P<month>[a-zA-Z]{3,})\.?-? ?(?P<day>\d\d?)(th|nd|st)?,?-? ?(?P<year>\d{4}))')) del dates_extracted[3] index_left = ~date_series.index.isin([x[0] for x in dates_extracted.index]) # Without day dates_without_day = date_series[index_left].str.extractall('(?P<origin>(?P<month>[A-Z][a-z]{2,}),?\.? (?P<year>\d{4}))') dates_without_day = dates_without_day.append(date_series[index_left].str.extractall(r'(?P<origin>(?P<month>\d\d?)/(?P<year>\d{4}))')) dates_without_day['day'] = 1 dates_extracted = dates_extracted.append(dates_without_day) index_left = ~date_series.index.isin([x[0] for x in dates_extracted.index]) # Only year dates_only_year = date_series[index_left].str.extractall(r'(?P<origin>(?P<year>\d{4}))') dates_only_year['day'] = 1 dates_only_year['month'] = 1 dates_extracted = dates_extracted.append(dates_only_year) index_left = ~date_series.index.isin([x[0] for x in dates_extracted.index]) # Year dates_extracted['year'] = dates_extracted['year'].apply(lambda x: '19' + x if len(x) == 2 else x) dates_extracted['year'] = dates_extracted['year'].apply(lambda x: str(x)) # Month dates_extracted['month'] = dates_extracted['month'].apply(lambda x: x[1:] if isinstance(x, str) and x.startswith('0') else x) month_dict = {'September': 9, 'Mar': 3, 'November': 11, 'Jul': 7, 'January': 1, 'December': 12, 'Feb': 2, 'May': 5, 'Aug': 8, 'Jun': 6, 'Sep': 9, 'Oct': 10, 'June': 6, 'March': 3, 'February': 2, 'Dec': 12, 'Apr': 4, 'Jan': 1, 'Janaury': 1,'August': 8, 'October': 10, 'July': 7, 'Since': 1, 'Nov': 11, 'April': 4, 'Decemeber': 12, 'Age': 8} dates_extracted.replace({"month": month_dict}, inplace=True) dates_extracted['month'] = dates_extracted['month'].apply(lambda x: str(x)) # Day dates_extracted['day'] = dates_extracted['day'].apply(lambda x: str(x)) # Cleaned date dates_extracted['date'] = dates_extracted['month'] + '/' + dates_extracted['day'] + '/' + dates_extracted['year'] dates_extracted['date'] = pd.to_datetime(dates_extracted['date']) dates_extracted.sort_values(by='date', inplace=True) df1 = pd.Series(list(dates_extracted.index.labels[0])) return df1
额外提示
- 调用函数时,记得传入你的DataFrame和目标列名,比如
date_sorter(your_df, target_col='your_date_column') - 可以先用
print(df.columns)确认你的目标列名称,避免填错
内容的提问来源于stack exchange,提问作者Mohd Amzad
相关产品推荐
相关产品推荐

