Понимание
Для петель это естественный и наивный способ производства декартовых продуктов.Понимания позволяют нам вложить это более кратко.
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
, встроенный в product
функция.product
- это итератор, который выводит каждую комбинацию по одной за раз.Я форсирую результат, распаковывая его с помощью *
, например [*product(a, b)]
.В конечном счете, это список списков, который передается конструктору pd.DataFrame
таким же образом, как и в описанном выше решении для понимания.
from itertools import product
pd.DataFrame([*product(df.LANE, range(12))], columns=['LANE', 'NUMBER'])
groupby
/ cumcount
и repeat
Мне не нравится этот ответ, но он дает некоторое представление о простоте других ответов.
Я использую repeat
для репликации каждого значения индекса 12 раз.Я использую этот повторяющийся индекс в loc
, который возвращает фрейм данных, разрезанный с переданным индексом.Затем я использую groupby
s cumcount
, чтобы сосчитать каждую позицию в группе и добавить ее в качестве нового столбца.
df.loc[df.index.repeat(12)].assign(NUMBER=lambda d: d.groupby('LANE').cumcount())
LANE NUMBER
0 a 0
0 a 1
0 a 2
0 a 3
0 a 4
0 a 5
0 a 6
0 a 7
0 a 8
0 a 9
0 a 10
0 a 11
1 b 0
1 b 1
1 b 2
1 b 3
1 b 4
1 b 5
1 b 6
1 b 7
1 b 8
1 b 9
1 b 10
1 b 11