【问题标题】:How to add rows to a dataframe based on the diff of two columns如何根据两列的差异向数据框添加行
【发布时间】:2025-11-28 09:40:01
【问题描述】:

我正在努力解决这个问题。

让我们假设一个如下所示的数据框:

df = pd.DataFrame({'col0':['string1', 'string2'],
                   'col1':['some string','another string'],
                   'start':[100,1],
                   'end':[107,5]})

      col0            col1  start  end
0  string1     some string    100  107
1  string2  another string      1    5

目标是找到startend 之间的差异,然后将那么多行添加到我的数据框中,ffill 其余列,并为startend。预期输出如下:

df2 = pd.DataFrame({'col0':['string1']*8, 
                    'col1':['some string']*8,
                    'new_col':[x for x in range(100,108)]})

df3 = pd.DataFrame({'col0':['string2']*5, 
                    'col1':['another string']*5,
                    'new_col':[x for x in range(1,6)]})

output = pd.concat([df2,df3]).reset_index(drop=True)

       col0            col1  new_col
0   string1     some string      100
1   string1     some string      101
2   string1     some string      102
3   string1     some string      103
4   string1     some string      104
5   string1     some string      105
6   string1     some string      106
7   string1     some string      107
8   string2  another string        1
9   string2  another string        2
10  string2  another string        3
11  string2  another string        4
12  string2  another string        5

我的第一个想法是创建一个新的数据框...类似于:

vals = list(zip(df['start'], df['end']+1))
pd.concat([pd.DataFrame([i], columns=['new_col']) for val in vals for i in range(*val)])

但这似乎效率很低,我正在努力添加剩余的数据。

【问题讨论】:

    标签: python python-3.x pandas


    【解决方案1】:

    1st使用range的for循环创建列表列,然后问题变成unnesting

    df['New']=[list(range(y,x+1)) for x , y in zip(df.pop('end'),df.pop('start'))]
    unnesting(df,['New'])
       New     col0            col1
    0  100  string1     some string
    0  101  string1     some string
    0  102  string1     some string
    0  103  string1     some string
    0  104  string1     some string
    0  105  string1     some string
    0  106  string1     some string
    0  107  string1     some string
    1    1  string2  another string
    1    2  string2  another string
    1    3  string2  another string
    1    4  string2  another string
    1    5  string2  another string
    

    仅供参考

    def unnesting(df, explode):
        idx=df.index.repeat(df[explode[0]].str.len())
        df1=pd.concat([pd.DataFrame({x:np.concatenate(df[x].values)} )for x in explode],axis=1)
        df1.index=idx
        return df1.join(df.drop(explode,1),how='left')
    

    【讨论】:

    • @Chris yw :-) -