Как взорвать диапазон (от двух столбцов) до строк - PullRequest
3 голосов
/ 19 сентября 2019

Привет всем, у меня есть это:

df = pd.DataFrame({'name':['L1', 'L2'], 'from':['1', '5'], 'to':['3', '7']})

name    from    to
L1       1       3
L2       5       7

На самом деле у меня много строк (3000000) и очень большой диапазон, например от 1 до 9000.

Каков наилучший способ получить такой результат (взорвать диапазон в строках)

вроде:

name    n°
L1       1
L1       2
L1       3
L2       5
L2       6
L2       7

Спасибо большое

Ответы [ 3 ]

1 голос
/ 19 сентября 2019

Использовать понимание списка с конструктором range и DataFrame:

df[['from','to']] = df[['from','to']].astype(int)

zipped = zip(df['name'], df['from'], df['to'])
df = pd.DataFrame([(i, y) for i,j,k in zipped for y in range(j, k+1)], columns=['name','id'])
print (df)
  name  id
0   L1   1
1   L1   2
2   L1   3
3   L2   5
4   L2   6
5   L2   7

Другое решение:

df[['from','to']] = df[['from','to']].astype(int)

s = df['to'] - df['from'] + 1
df = df.loc[df.index.repeat(s), ['name','from']].rename(columns={'from':'no'})
df['no'] += df.groupby(level=0).cumcount()
df = df.reset_index(drop=True)
print (df)
  name  no
0   L1   1
1   L1   2
2   L1   3
3   L2   5
4   L2   6
5   L2   7
0 голосов
/ 19 сентября 2019

Отредактировано : извините, я неправильно ответила на вопросы 1 раз, я исправила ответ

Поскольку данные панд хранятся внутри массива numpy, а операции numpy выполняются быстро, вы можете использовать numpy манипуляции длясделай это

import pandas as pd
import numpy as np

df = pd.DataFrame({'name':['L1', 'L2'], 'from':[1, 5], 'to':[3, 7]})

t_dict = {}
## find number of times each rows should be repeated
repeats = (df["to"]- df["from"]+1 ).values

## repeat names
t_dict["name"] = df["name"].values.repeat(repeats)

## repeat notes and add 0,1,2,3 .. seq to each repeated section
t_dict["n°"] = df["from"].values.repeat(repeats) + np.array([i for count in repeats for i in range(count)])

pd.DataFrame(t_dict)

вывод

name    n°
0   L1  1
1   L1  2
2   L1  3
3   L2  5
4   L2  6
5   L2  7
0 голосов
/ 19 сентября 2019
(pd.concat([df, df[['from', 'to']]
           .applymap(int)
           .apply(lambda x: np.arange(x[0], x[1]), axis=1)], 
          axis=1)
.explode(0))

Выход:

    name    from    to  0
0   L1         1    3   1
0   L1         1    3   2
1   L2         5    7   5
1   L2         5    7   6
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...