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

如何将单列字符串转换为DataFrame?修正代码及替代方案咨询

问题修正与替代方案

一、正则表达式修正

原正则的问题在于启用re.S(DOTALL)模式后,.*会贪婪匹配到文本末尾,导致第一个日期把后续所有内容(包括第二个日期)都纳入匹配范围。修正思路是用非贪婪匹配+正向预查,限制匹配范围到下一个日期开头或文本结尾:

修正后的代码:

import re
import pandas as pd

text = '''10 February 2023
abc
def
23 March 2023
ghi
jkl'''

data = []
# 正则解释:匹配日期行,然后匹配后续内容直到下一个日期行或文本结束
for m in re.finditer(r'(\d+ \w+ \d+)\n(.*?)(?=\n\d+ \w+ \d+|$)', text, flags=re.I|re.S):
    data.append([m.group(1), m.group(2).splitlines()])
    
df = pd.DataFrame(data, columns=['date', 'letters']).explode('letters')
print(df)

输出结果:

date letters
0  10 February 2023     abc
0  10 February 2023     def
1     23 March 2023     ghi
1     23 March 2023     jkl

二、其他实现方案

方案1:逐行遍历分组

无需正则,通过判断行类型(日期/普通行)手动分组:

import pandas as pd

text = '''10 February 2023
abc
def
23 March 2023
ghi
jkl'''

lines = text.splitlines()
data = []
current_date = None
current_letters = []

for line in lines:
    parts = line.split()
    # 简单判断日期行:分割为3部分,首尾是数字
    if len(parts) == 3 and parts[0].isdigit() and parts[2].isdigit():
        if current_date:
            data.append([current_date, current_letters])
        current_date = line
        current_letters = []
    else:
        current_letters.append(line)
# 处理最后一组数据
if current_date:
    data.append([current_date, current_letters])

df = pd.DataFrame(data, columns=['date', 'letters']).explode('letters')
print(df)

方案2:Pandas原生分组技巧

利用Pandas的where和ffill方法自动填充日期分组:

import pandas as pd

text = '''10 February 2023
abc
def
23 March 2023
ghi
jkl'''

# 将文本转为Series
s = pd.Series(text.splitlines())
# 标记日期行
is_date = s.str.match(r'\d+ \w+ \d+', case=False)
# 用前一个日期填充后续非日期行
dates = s.where(is_date).ffill()
# 过滤掉日期行,生成结果
result = pd.DataFrame({
    'date': dates[~is_date],
    'letters': s[~is_date]
}).reset_index(drop=True)
print(result)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 12:23:45