根据2列的范围将新行插入pandas数据框

时间:2019-02-28 03:37:48

标签: python pandas dataframe

我有一个df,例如:

ID       value1   start     end
 1         100     1        2       
 1         200     2        4
 2         50      1        1
 2         30      3        5 

我要为开始和结束之间的每个值填写新行

最终df应该看起来像这样,其中period是开始和结束之间的每个唯一值

    ID       value1      period     
     1         100     1        
     1         100     2            
     1         200     2 
     1         200     3 
     1         200     4       
     2         50      1        
     2         30      3    
     2         30      4 
     2         30      5     

2 个答案:

答案 0 :(得分:1)

使用for循环后,用range创建列列表,这成为unnesting问题

df['New']=[list(range(x,y+1)) for x , y in zip(df.start,df.end)]
Yourdf=unnesting(df,['New'])
Yourdf
   New  ID  value1  start  end
0    1   1     100      1    2
0    2   1     100      1    2
1    2   1     200      2    4
1    3   1     200      2    4
1    4   1     200      2    4
2    1   2      50      1    1
3    3   2      30      3    5
3    4   2      30      3    5
3    5   2      30      3    5

答案 1 :(得分:1)

或使用下面的列表理解:

>>> df['period']=[','.join(map(str,range(x,y+1))) for x,y in zip(df['start'],df['end'])]
>>> df.set_index(['ID','value1','start','end']).stack().str.split(',', expand=True).stack().unstack(-2).reset_index(-1,drop=True).reset_index()
   ID  value1  start  end period
0   1     100      1    2      1
1   1     100      1    2      2
2   1     200      2    4      2
3   1     200      2    4      3
4   1     200      2    4      4
5   2      30      3    5      3
6   2      30      3    5      4
7   2      30      3    5      5
8   2      50      1    1      1
>>> 

如果要删除列:

>>> df['period']=[','.join(map(str,range(x,y+1))) for x,y in zip(df.pop('start'),df.pop('end'))]
>>> df.set_index(['ID','value1']).stack().str.split(',', expand=True).stack().unstack(-2).reset_index(-1,drop=True).reset_index()
   ID  value1 period
0   1     100      1
1   1     100      2
2   1     200      2
3   1     200      3
4   1     200      4
5   2      30      3
6   2      30      4
7   2      30      5
8   2      50      1
>>>