使用Python创建一列,该列的值的范围取决于另一列

使用Python创建一列,该列的值的范围取决于另一列,python,pandas,range,Python,Pandas,Range,我有一个数据框,其中包含具有关联值的ID以及每个值的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 rang

我有一个数据框,其中包含具有关联值的ID以及每个值的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
任何提示或建议都将不胜感激


谢谢

选项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
使用
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

pandas。重复
,然后使用
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

pandas。重复
,然后使用
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

您使用的是哪种数据结构?是列表列表,还是Pandas数据框,还是其他什么?抱歉,这是Pandas数据框。在这种情况下,您应该编辑问题以反映这一点,方法是添加标记,并在文本中明确提到您正在使用
数据框。如果您可以包含一个演示问题的示例代码,这也会有所帮助-例如,您可以扩展发布的示例代码,以包含一段代码,用示例数据创建一个
DataFrame
。我们的目标是得到人们可以复制粘贴到文件中的东西,然后运行来重现您的问题。您使用的是什么样的数据结构?是列表列表,还是Pandas数据框,还是其他什么?抱歉,这是Pandas数据框。在这种情况下,您应该编辑问题以反映这一点,方法是添加标记,并在文本中明确提到您正在使用
数据框。如果您可以包含一个演示问题的示例代码,这也会有所帮助-例如,您可以扩展发布的示例代码,以包含一段代码,用示例数据创建一个
DataFrame
。我们的目标是得到人们可以复制粘贴到文件中的东西,然后运行来重现您的问题。谢谢@piRSquared。但是,我需要的关键一点是,范围是可以确定的。我试图通过改变重复次数以及
[-1,0,1]
来改变你答案中的+/-1,但没有效果。谢谢@piRSquared。但是,我需要的关键一点是,范围是可以确定的。我试图通过改变重复次数以及
[-1,0,1]
来改变答案中的+/-1,但没有效果。