循环为给定范围的数字创建新行

时间:2018-09-19 14:52:44

标签: python pandas loops

我确信这是一个简单的解决方法,但是我无法找到解决我问题的确切方法。我的数据集有一个名为“ LANE”的列,其中包含唯一值。我想基于一系列数字(将是0到12)为每个“ LANE”添加行。结果,每个“ LANE”将有13行,新列“ NUMBER”的范围为0到12,包括12。

示例:

输入

LANE
a
b

输出

LANE    NUMBER
a       0
a       1
a       2
a       3
a       4
a       5
a       6
a       7
a       8
a       9
a       10
a       11
a       12
b       0
b       1
b       2
b       3
b       4
b       5
b       6
b       7
b       8
b       9
b       10
b       11
b       12

我目前正在尝试以下几种形式:

num = 0

while num <= 12:
    for x in df['LANE']:
        df['NUMBER'] = num
    num += 1

此循环的问题是,我仍然为每个泳道保留一条记录,并且“ NUMBER”列的值仅为12。

2 个答案:

答案 0 :(得分:4)

理解力

For循环是生产笛卡尔积的自然而幼稚的方法。理解使我们能够更简洁地嵌入其中。

pd.DataFrame(
    [[l, n] for l in df.LANE for n in range(12)],
    columns=['LANE', 'NUMBER']
)

   LANE  NUMBER
0     a       0
1     a       1
2     a       2
3     a       3
4     a       4
5     a       5
6     a       6
7     a       7
8     a       8
9     a       9
10    a      10
11    a      11
12    b       0
13    b       1
14    b       2
15    b       3
16    b       4
17    b       5
18    b       6
19    b       7
20    b       8
21    b       9
22    b      10
23    b      11

itertools.product

此逻辑几乎与理解解决方案相同,但是使用内置于itertools函数中的productproduct是一个迭代器,每次弹出一个组合。我通过像*一样用splat [*product(a, b)]解压缩来强制结果。最终,这是一个列表列表,该列表以与上述理解解决方案相同的方式传递到pd.DataFrame构造函数。

from itertools import product

pd.DataFrame([*product(df.LANE, range(12))], columns=['LANE', 'NUMBER'])

groupby / cumcountrepeat

我不喜欢这个答案,但是它为其他答案的简单性提供了一些视角。

我使用repeat将每个索引值复制12次。我在loc中使用了这个重复的索引,该索引返回一个被传递的索引切片的数据帧。然后,我使用groupby的{​​{1}}来计算组中的每个职位,并将其添加为新列。

cumcount

答案 1 :(得分:0)

另一种使用熊猫的方法如下:

# First approach, one liner code
df = pd.DataFrame({'Lane': ['a'] * 12 + ['b'] * 12,
                   'Number': list(range(12)) * 2})

# Second approach
df = pd.DataFrame({'Lane': ['a'] * 12 + ['b'] * 12})
df['Number'] = df.groupby('Lane').cumcount()