Расширение строк фрейма данных панд на основе номера и идентификатора группы (Python 3).

Я изо всех сил пытался найти способ расширить / клонировать ряды наблюдений на основе заранее определенного числа и переменной группировки (id). Для контекста, вот пример фрейма данных с использованием панд и numpy (python3).

df = pd.DataFrame([[1, 15], [2, 20]], columns = ['id', 'num'])

df
Out[54]:
  id  num
0   1   15
1   2   20 

Я хочу расширить / клонировать строки по номеру, указанному в переменной "num" на основе их группы идентификаторов. В этом случае я бы хотел 15 строк для id = 1 и 20 строк для id = 2. Это, вероятно, простой вопрос, но я изо всех сил стараюсь сделать эту работу. Я возился с reindex и np.repeat, но концептуальные части мне не подходят.

В R я использовал функцию expandRows из пакета splitstackshape, которая бы выглядела примерно так:

library(splitstackshape)

df <- data.frame(id = c(1, 2), num = c(15, 20))


df
  id num
1  1  15
2  2  20


df2 <- expandRows(df, "num", drop = FALSE)
df2
     id num
1     1  15
1.1   1  15
1.2   1  15
1.3   1  15
1.4   1  15
1.5   1  15
1.6   1  15
1.7   1  15
1.8   1  15
1.9   1  15
1.10  1  15
1.11  1  15
1.12  1  15
1.13  1  15
1.14  1  15
2     2  20
2.1   2  20
2.2   2  20
2.3   2  20
2.4   2  20
2.5   2  20
2.6   2  20
2.7   2  20
2.8   2  20
2.9   2  20
2.10  2  20
2.11  2  20
2.12  2  20
2.13  2  20
2.14  2  20
2.15  2  20
2.16  2  20
2.17  2  20
2.18  2  20
2.19  2  20

Опять же, извините, если это глупый вопрос, и заранее спасибо за любую помощь.

1 ответ

Решение

Я не могу воспроизвести ваш индекс, но я могу скопировать ваши значения, используя np.repeatдовольно легко на самом деле.

v = df.values
df = pd.DataFrame(v.repeat(v[:, -1], axis=0), columns=df.columns)
df

    id  num
0    1   15
1    1   15
2    1   15
3    1   15
4    1   15
5    1   15
6    1   15
7    1   15
8    1   15
9    1   15
10   1   15
11   1   15
12   1   15
13   1   15
14   1   15
15   2   20
16   2   20
17   2   20
18   2   20
19   2   20
20   2   20
21   2   20
22   2   20
23   2   20
24   2   20
25   2   20
26   2   20
27   2   20
28   2   20
29   2   20
30   2   20
31   2   20
32   2   20
33   2   20
34   2   20

Если вам нужен точный индекс (хотя я не понимаю, зачем вам это нужно), вам понадобится groupby операция -

def f(x):
    return x.astype(str) + '.' + np.arange(len(x)).astype(str)

idx = df.groupby('id').id.apply(f).values
idx 
array(['1.0', '1.1', '1.2', '1.3', '1.4', '1.5', '1.6', '1.7', '1.8',
       '1.9', '1.10', '1.11', '1.12', '1.13', '1.14', '2.0', '2.1', '2.2',
       '2.3', '2.4', '2.5', '2.6', '2.7', '2.8', '2.9', '2.10', '2.11',
       '2.12', '2.13', '2.14', '2.15', '2.16', '2.17', '2.18', '2.19'], dtype=object)

приписывать idx в dfИндекс -

df.index = idx
Другие вопросы по тегам