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”列的值除以构造:
原始 table 的 5.15 乘以 MIN_RAT=1 和 MAX_RAT = 2 之间的新行数,并将该值添加到 5.15(在此如果我们在每一行中添加 0.515)
原始 table 的 2,55 乘以 MIN_RAT=2,1 和 MAX_RAT = 3 之间的新行数,并将该值添加到2.55(在这种情况下,我们在每行中添加 0.28)
是否可以优化此操作?
假设初始数据帧是:
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
我有这样一个数据框:
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”列的值除以构造:
-
原始 table 的
5.15 乘以 MIN_RAT=1 和 MAX_RAT = 2 之间的新行数,并将该值添加到 5.15(在此如果我们在每一行中添加 0.515)
原始 table 的 2,55 乘以 MIN_RAT=2,1 和 MAX_RAT = 3 之间的新行数,并将该值添加到2.55(在这种情况下,我们在每行中添加 0.28)
是否可以优化此操作?
假设初始数据帧是:
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