Expand Pandas Dataframes 按不同范围添加行

Expand Pandas Dataframes adding rows by different ranges

我有这样一个数据框:

SEG FAM GAMA MIN_RAT MAX_RAT 勇气
PE 001 002 1 2 5,15
PE 001 002 2,1 3 2,55

而且我需要“扩展”df 添加新行来制作一个新的数据框,如下所示:

SEG FAM GAMA MIN_RAT MAX_RAT 勇气
PE 001 002 1 1 10,30
PE 001 002 1,1 1,1 9,79
PE 001 002 1,2 1,2 9,27
PE 001 002 1,3 1,3 8,76
PE 001 002 1,4 1,4 8,24
PE 001 002 1,5 1,5 7,73
PE 001 002 1,6 1,6 7,21
PE 001 002 1,7 1,7 6,70
PE 001 002 1,8 1,8 6,18
PE 001 002 1,9 1,9 5,67
PE 001 002 2 2 5,15
PE 001 002 2,1 2,1 5,10
PE 001 002 2,2 2,2 4,82
PE 001 002 2,3 2,3 4,53
PE 001 002 2,4 2,4 4,25
PE 001 002 2,5 2,5 3,97
PE 001 002 2,6 2,6 3,68
PE 001 002 2,7 2,7 3,40
PE 001 002 2,8 2,8 3,12
PE 001 002 2,9 2,9 2,83
PE 001 002 3 3 2,55

“VALOR”列的值除以构造:

是否可以优化此操作?

假设初始数据帧是:

df = pd.DataFrame([['PE', 1,2,1,2,5.15], ['PE', 1,2,2.1,3,2.55]],
                  columns=['SEG', 'FAM', 'GAMA', 'MIN_RAT', 'MAX_RAT', 'VALOR'])

你可以这样做:

import numpy as np
import pandas as pd
def extrapolate(s):
    start = s['MIN_RAT']
    stop  = s['MAX_RAT']
    value = s['VALOR']
    n = int((stop-start)/0.1)+1
    d = pd.concat([s for i in range(n)], axis=1).T
    d['MIN_RAT'] = np.linspace(start, stop, n)
    d['MAX_RAT'] = df['MIN_RAT']
    d['VALOR']   = np.linspace(2*value, value, n)
    return d

pd.concat([extrapolate(s) for _,s in df.iterrows()])

输出:

  SEG FAM GAMA  MIN_RAT  MAX_RAT     VALOR
0  PE   1    2   1.0000   1.0000  10.30000
0  PE   1    2   1.1000   1.1000   9.78500
0  PE   1    2   1.2000   1.2000   9.27000
0  PE   1    2   1.3000   1.3000   8.75500
0  PE   1    2   1.4000   1.4000   8.24000
0  PE   1    2   1.5000   1.5000   7.72500
0  PE   1    2   1.6000   1.6000   7.21000
0  PE   1    2   1.7000   1.7000   6.69500
0  PE   1    2   1.8000   1.8000   6.18000
0  PE   1    2   1.9000   1.9000   5.66500
0  PE   1    2   2.0000   2.0000   5.15000
1  PE   1    2   2.1000   2.1000   5.10000
1  PE   1    2   2.2125   2.2125   4.78125
1  PE   1    2   2.3250   2.3250   4.46250
1  PE   1    2   2.4375   2.4375   4.14375
1  PE   1    2   2.5500   2.5500   3.82500
1  PE   1    2   2.6625   2.6625   3.50625
1  PE   1    2   2.7750   2.7750   3.18750
1  PE   1    2   2.8875   2.8875   2.86875
1  PE   1    2   3.0000   3.0000   2.55000

让我们试试这个:

rnglist=[np.arange(i, j+.1, 0.1) for i, j in list(zip(df['MIN_RAT'], df['MAX_RAT']))]

dfm = df.reindex(df.index.repeat([len(x) for x in rnglist]))

dfm['MIN_RAT'] = np.concatenate(rnglist)
dfm['MAX_RAT'] = np.concatenate(rnglist)

dfm['VALOR']=  dfm.groupby(level=0)['VALOR']\
                  .transform(lambda x: ((x.notna().cumsum()-1)/(x.count()-1)*x.iloc[0])[::-1]+x.iloc[0])
print(dfm)

输出:

   EG  FAM  GAMA  MIN_RAT  MAX_RAT      VALOR
0  PE    1     2      1.0      1.0  10.300000
0  PE    1     2      1.1      1.1   9.785000
0  PE    1     2      1.2      1.2   9.270000
0  PE    1     2      1.3      1.3   8.755000
0  PE    1     2      1.4      1.4   8.240000
0  PE    1     2      1.5      1.5   7.725000
0  PE    1     2      1.6      1.6   7.210000
0  PE    1     2      1.7      1.7   6.695000
0  PE    1     2      1.8      1.8   6.180000
0  PE    1     2      1.9      1.9   5.665000
0  PE    1     2      2.0      2.0   5.150000
1  PE    1     2      2.1      2.1   5.100000
1  PE    1     2      2.2      2.2   4.816667
1  PE    1     2      2.3      2.3   4.533333
1  PE    1     2      2.4      2.4   4.250000
1  PE    1     2      2.5      2.5   3.966667
1  PE    1     2      2.6      2.6   3.683333
1  PE    1     2      2.7      2.7   3.400000
1  PE    1     2      2.8      2.8   3.116667
1  PE    1     2      2.9      2.9   2.833333
1  PE    1     2      3.0      3.0   2.550000