使用Python创建具有依赖于另一列的范围中的值的列

时间:2017-10-04 00:09:14

标签: python pandas range

我有一个Pandas DataFrame,其中包含具有关联值的ID以及每个值,我想创建一个新列,其值的范围大于初始值可确定的金额。我的初始数据看起来像这样;

iD     Value
AAAA   10
AAAA   15
AAAA   5
BBBB   10
BBBB   6
BBBB   11
CCCC   8 
CCCC   16
CCCC   14

我到目前为止的代码如下,其中范围设置为+/- 1;

def add_range(lower, higher, oldval):
for i in range(lower,higher):
    print i
    newval = oldval + i
return newel

lower = -1
higher = 1

MSet['NewVal'] = MSet.apply(lambda row: add_range(row['Ords'],lower,higher), axis =1)

我想要的是;

iD     Value   NewVal
AAAA   10      9
AAAA   10      10
AAAA   10      11
AAAA   15      14
AAAA   15      15
AAAA   15      16
AAAA   5       4
AAAA   5       5
AAAA   5       6
BBBB   10      9
BBBB   10      10
BBBB   10      11
BBBB   6       5
BBBB   6       6
BBBB   6       7      
BBBB   11      10
BBBB   11      11
BBBB   11      12
CCCC   8       7
CCCC   8       8
CCCC   8       9
CCCC   16      14
CCCC   16      15
CCCC   16      16
CCCC   14      13
CCCC   14      14
CCCC   14      15

任何提示或建议都会受到高度赞赏。

谢谢!

2 个答案:

答案 0 :(得分:3)

选项1
使用loc

更简单
df.loc[df.index.repeat(3)].assign(
    NewVal=(df.Value.values[:, None] + [-1, 0, 1]).ravel())

选项2
或者重建整个数据框

i = df.iD.values
v = df.Value.values

pd.DataFrame(
    np.column_stack([
        i.repeat(3),
        v.repeat(3),
        (v[:, None] + [-1, 0, 1]).ravel()
    ]), columns=['iD', 'Value', 'NewVal']
)

这两个选项都使用numpy广播将[-1, 0, 1]添加到值,然后使用ravel

      iD Value NewVal
0   AAAA    10      9
1   AAAA    10     10
2   AAAA    10     11
3   AAAA    15     14
4   AAAA    15     15
5   AAAA    15     16
6   AAAA     5      4
7   AAAA     5      5
8   AAAA     5      6
9   BBBB    10      9
10  BBBB    10     10
11  BBBB    10     11
12  BBBB     6      5
13  BBBB     6      6
14  BBBB     6      7
15  BBBB    11     10
16  BBBB    11     11
17  BBBB    11     12
18  CCCC     8      7
19  CCCC     8      8
20  CCCC     8      9
21  CCCC    16     15
22  CCCC    16     16
23  CCCC    16     17
24  CCCC    14     13
25  CCCC    14     14
26  CCCC    14     15

答案 1 :(得分:1)

pandas.repeat,然后使用groupby,并取消列出

df1=df.loc[df.index.repeat(3)]
import operator
df1.groupby(['iD','Value'],as_index=False).apply(lambda x :list(map(operator.sub, x['Value'], [1,0,-1]))).\
    apply(pd.Series).stack().reset_index().\
        drop('level_2',1).rename(columns={0:'New'})

Out[253]: 
      iD  Value  New
0   AAAA      5    4
1   AAAA      5    5
2   AAAA      5    6
3   AAAA     10    9
4   AAAA     10   10
5   AAAA     10   11
6   AAAA     15   14
7   AAAA     15   15
8   AAAA     15   16
9   BBBB      6    5
10  BBBB      6    6
11  BBBB      6    7
12  BBBB     10    9
13  BBBB     10   10
14  BBBB     10   11
15  BBBB     11   10
16  BBBB     11   11
17  BBBB     11   12
18  CCCC      8    7
19  CCCC      8    8
20  CCCC      8    9
21  CCCC     14   13
22  CCCC     14   14
23  CCCC     14   15
24  CCCC     16   15
25  CCCC     16   16
26  CCCC     16   17