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

基于字符串规则拆分DataFrame行生成多行数据的实现方法

基于字符串规则拆分DataFrame行生成多行数据的实现方法

看起来你需要处理DataFrame里格式多变的地址字符串,把里面的数字范围或单个数字拆成独立行,同时保留其他列的信息对吧?我刚好有个高效的解决方案,能覆盖你提到的几种格式(奇偶范围、to连接的范围、逗号分隔的单个数字),还能处理大小写变化的问题。

解决方案思路

核心是用正则表达式匹配不同格式的数字规则,生成对应的数字序列,再把每个数字和地址后缀拼接,最后用explode把列表拆分成多行。

完整代码实现

import pandas as pd
import re

def expand_address(address_str):
    # 提取地址后缀(路名部分),忽略大小写匹配
    suffix_match = re.search(r'(?<=\d)(?:\s*\(.*?\))?\s+(.*)', address_str, re.IGNORECASE)
    suffix = suffix_match.group(1) if suffix_match else ""
    
    # 情况1: 匹配类似 "220-224 (Even)" 或 "5-9 (Odd)" 的范围格式
    range_dash_match = re.search(r'(\d+)-(\d+)\s*\((Even|Odd)\)', address_str, re.IGNORECASE)
    if range_dash_match:
        start = int(range_dash_match.group(1))
        end = int(range_dash_match.group(2))
        parity = range_dash_match.group(3).lower()
        # 根据奇偶调整起始值和步长
        step = 2
        if parity == 'even' and start % 2 != 0:
            start += 1
        elif parity == 'odd' and start % 2 == 0:
            start += 1
        # 生成包含结束值的数字序列
        nums = list(range(start, end + 1, step))
        return [f"{num} {suffix}" for num in nums]
    
    # 情况2: 匹配类似 "site of 5 to 9 (odd)" 的范围格式
    range_to_match = re.search(r'(\d+)\s+to\s+(\d+)\s*\((Even|Odd)\)', address_str, re.IGNORECASE)
    if range_to_match:
        start = int(range_to_match.group(1))
        end = int(range_to_match.group(2))
        parity = range_to_match.group(3).lower()
        step = 2
        if parity == 'even' and start % 2 != 0:
            start += 1
        elif parity == 'odd' and start % 2 == 0:
            start += 1
        nums = list(range(start, end + 1, step))
        return [f"{num} {suffix}" for num in nums]
    
    # 情况3: 匹配类似 "16, 19" 的单个数字列表格式
    single_nums_match = re.findall(r'(\d+)', address_str)
    if single_nums_match:
        return [f"{num} {suffix}" for num in single_nums_match]
    
    # 兜底:如果都匹配不到,返回原字符串
    return [address_str]

# 你的原始数据
df = pd.DataFrame([
    {'var1': '220-224 (Even) roadname1', 'var2': 'location 1', 'var3': 'area 1'},
    {'var1': 'site of 5 to 9 (odd) roadname2', 'var2': 'location 2', 'var3': 'area 2'},
    {'var1': '16, 19 roadname3', 'var2': 'location 3', 'var3': 'area 3'}
])

# 处理var1列生成列表,再拆分成多行
df['var1'] = df['var1'].apply(expand_address)
result_df = df.explode('var1').reset_index(drop=True)

print(result_df)

代码解释

  1. 提取地址后缀:用正则跳过数字和奇偶标识部分,直接提取后面的路名,兼容不同格式的前缀内容。
  2. 三种数字格式处理:
    • 针对数字-数字 (奇偶)格式:提取起止数字和奇偶类型,生成对应步长的数字序列。
    • 针对数字 to 数字 (奇偶)格式:逻辑和上面一致,只是匹配to关键词。
    • 针对逗号分隔的单个数字:直接提取所有数字生成独立条目。
  3. 拆分多行:用df.explode('var1')把每行的var1列表拆成独立行,同时自动保留var2和var3的对应内容。

运行结果

var1        var2    var3
0  220 roadname1  location 1  area 1
1  222 roadname1  location 1  area 1
2  224 roadname1  location 1  area 1
3    5 roadname2  location 2  area 2
4    7 roadname2  location 2  area 2
5    9 roadname2  location 2  area 2
6   16 roadname3  location 3  area 3
7   19 roadname3  location 3  area 3

这个方案还能兼容大小写变化(比如(even)或(ODD)都能识别),如果后续有其他格式,只需要添加对应的正则匹配分支即可。

备注:内容来源于stack exchange,提问作者suzanne

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.15 10:39:34