将数值范围转换为连续序列:Pandas数据集展开问题求助
解决Pandas中范围格式字段的行展开问题
首先得指出你初始代码里的一个小问题:你定义字典d时,Terri的值写的是1-5和6-10,这在Python里会被直接计算成数值(1-5=-4,6-10=-4),而不是你需要的范围字符串格式。所以第一步得把Terri的内容改成字符串形式,比如"1-5"、"6-10"。
接下来,我们用自定义函数+explode方法就能轻松实现你想要的行展开效果,具体步骤如下:
步骤1:修正初始数据格式
先把输入数据调整为正确的字符串范围格式:
import pandas as pd # 修正Terri为字符串格式的范围 d = {'Peril':['Fire','Wind'], 'Terri':["1-5","6-10"], 'Premium':[100,200]} df = pd.DataFrame(data=d)
步骤2:编写范围展开函数
定义一个函数,输入范围字符串(如"1-5"),返回对应的数值列表:
def expand_territory(terri_str): # 拆分起始和结束值,转为整数 start, end = map(int, terri_str.split('-')) # 返回包含起始到结束所有数值的列表(注意要包含end,所以range要+1) return list(range(start, end + 1))
步骤3:应用函数并展开行
用apply把函数作用到Terri列生成数值列表,再用explode把列表拆分成多行:
# 生成包含数值列表的临时列 df['Terri_expanded'] = df['Terri'].apply(expand_territory) # 展开列表为多行,并重命名列 result_df = df.explode('Terri_expanded').rename(columns={'Terri_expanded': 'Terri'}) # 不需要原Terri列的话可以删除 result_df = result_df.drop('Terri', axis=1)
验证结果
现在输出的result_df就和你预期的expected_output完全一致了:
expected_output = pd.DataFrame(data={ 'Peril':['Fire','Fire','Fire','Fire','Fire','Wind','Wind','Wind','Wind','Wind'], 'Terri':[1,2,3,4,5,6,7,8,9,10], 'Premium':[100,100,100,100,100,200,200,200,200,200] }) # 检查是否匹配 print(result_df.equals(expected_output)) # 输出True
处理多范围的复杂情况(如[1-5,10-99,100-115])
如果你的Territory字段是包含多个范围的字符串(比如"1-5,10-99,100-115"),只需要稍微修改展开函数,先按逗号拆分多个范围,再逐个处理:
def expand_complex_territory(terri_str): all_values = [] # 拆分多个范围 ranges = terri_str.split(',') for r in ranges: start, end = map(int, r.split('-')) all_values.extend(range(start, end + 1)) return all_values # 示例使用 df_complex = pd.DataFrame({ 'Peril':['Flood'], 'Terri':["1-5,10-12"], 'Premium':[300] }) df_complex['Terri_expanded'] = df_complex['Terri'].apply(expand_complex_territory) result_complex = df_complex.explode('Terri_expanded').drop('Terri', axis=1) print(result_complex)
输出结果:
Peril Terri_expanded Premium 0 Flood 1 300 0 Flood 2 300 0 Flood 3 300 0 Flood 4 300 0 Flood 5 300 0 Flood 10 300 0 Flood 11 300 0 Flood 12 300
针对9000条记录的性能说明
你的数据集有9000条记录,上面的方法完全能高效处理——apply+explode的组合在这个量级下不会有性能瓶颈。如果后续数据量再大幅增长,也可以改用numpy生成序列的方式进一步优化,但目前这个方案已经足够好用。
内容的提问来源于stack exchange,提问作者Bjc51192
相关产品推荐
相关产品推荐

