如何用Python Pandas实现含字母数字列的行按序列重复展开?
处理Pandas中带字符前缀的序列展开问题
问题描述
有如下结构的Pandas DataFrame,需根据to列的值,将每行按from到to的序列展开为多行:
data from to abc 1 3 bcd 1 4 klm T1 T4 GKN R123 R125
期望输出:
data from to abc 1 3 abc 2 3 abc 3 3 bcd 1 4 bcd 2 4 bcd 3 4 bcd 4 4 klm T1 T4 klm T2 T4 klm T3 T4 klm T4 T4 GKN R123 R125 GKN R124 R125 GKN R125 R125
已实现纯数字列的处理代码:
df = df.loc[df.index.repeat(df['to'] - df['from'] + 1)] df['from'] = df.groupby(level=0).cumcount() + df['from'] df = df.reset_index(drop=True)
但对带字符前缀的字母数字列(如T1/T4、R123/R125)处理存在困难,以下是解决方法:
解决方案
核心思路是拆分带前缀字符串的字符前缀与数字部分,对数字部分生成序列后再拼接前缀,兼容纯数字场景。
1. 拆分前缀与数字
通过正则表达式提取字符串中的前缀和数字:
import pandas as pd import re def split_prefix_num(s): # 匹配前缀+数字的格式 match = re.match(r'([A-Za-z]+)(\d+)', str(s)) if match: return match.group(1), int(match.group(2)) # 纯数字返回空前缀和数字本身 return '', int(s) # 对from、to列拆分前缀和数字 df[['from_prefix', 'from_num']] = df['from'].apply(lambda x: pd.Series(split_prefix_num(x))) df[['to_prefix', 'to_num']] = df['to'].apply(lambda x: pd.Series(split_prefix_num(x)))
2. 展开行
利用数字部分计算每行需要重复的次数,按索引重复行:
df_expanded = df.loc[df.index.repeat(df['to_num'] - df['from_num'] + 1)]
3. 生成新的from列值
分组后生成递增的数字序列,再与前缀拼接得到新的from值:
# 生成递增数字序列 df_expanded['new_from_num'] = df_expanded.groupby(level=0).cumcount() + df_expanded['from_num'] # 拼接前缀与数字 df_expanded['from'] = df_expanded['from_prefix'] + df_expanded['new_from_num'].astype(str)
4. 整理结果
删除辅助列并重置索引:
result = df_expanded[['data', 'from', 'to']].reset_index(drop=True)
完整可运行代码
import pandas as pd import re def split_prefix_num(s): match = re.match(r'([A-Za-z]+)(\d+)', str(s)) if match: return match.group(1), int(match.group(2)) return '', int(s) # 构造示例DataFrame df = pd.DataFrame({ 'data': ['abc', 'bcd', 'klm', 'GKN'], 'from': ['1', '1', 'T1', 'R123'], 'to': ['3', '4', 'T4', 'R125'] }) # 拆分前缀与数字 df[['from_prefix', 'from_num']] = df['from'].apply(lambda x: pd.Series(split_prefix_num(x))) df[['to_prefix', 'to_num']] = df['to'].apply(lambda x: pd.Series(split_prefix_num(x))) # 展开行 df_expanded = df.loc[df.index.repeat(df['to_num'] - df['from_num'] + 1)] # 生成新from列 df_expanded['new_from_num'] = df_expanded.groupby(level=0).cumcount() + df_expanded['from_num'] df_expanded['from'] = df_expanded['from_prefix'] + df_expanded['new_from_num'].astype(str) # 整理结果 result = df_expanded[['data', 'from', 'to']].reset_index(drop=True) print(result)
运行上述代码即可得到符合要求的输出,同时兼容纯数字和带前缀的字母数字两种场景。
内容的提问来源于stack exchange,提问作者Krispy
相关产品推荐
相关产品推荐

