Самый быстрый способ уменьшить последовательный индекс значений до набора последовательных диапазонов для каждого значения в python - PullRequest
3 голосов
/ 03 мая 2020

У меня есть большой Panda Dataframe, где индекс представляет собой последовательные целые числа. Столбец соответствует значению в этом положении, например, игрушка:

a = pd.DataFrame(index=range(7),data = [1.3,1.3,1.3,0.4,0.6,0.6,1.3], columns=['Values'])
     Values
0    1.3
1    1.3
2    1.3
3    0.4
4    0.6
5    0.6
6    1.3

Есть ли быстрый способ вместо этого уменьшить набор последовательных диапазонов:

start    end    Values
0        3        1.3
3        4        0.4
4        6        0.6
6        7        1.3

У меня есть исключить итерацию строки за строкой слишком медленно. Вдохновившись этим ответом в Stack Exchange Code Review , я использовал шаблон enumerate + groupby для каждого уникального значения:

for val in set(a['Values'].values):
    index = list(a[list(a['Values'] == val)].index.values)
    for _, g in groupby(index, key=lambda n, c=count(): n-next(c)):
        l = list(g)
        print(l[0], l[-1]+1, val)

3    4    0.4
0    3    1.3
6    7    1.3
4    6    0.6

, которое затем можно сохранить и отсортировать. Есть ли способ улучшить это для улучшения производительности в python?

Ответы [ 2 ]

3 голосов
/ 03 мая 2020

Создайте ключ groupby с diff и cumsum, do groupby

b=a.reset_index().groupby(a.Values.diff().ne(0).cumsum()).\
      agg(start=('index','min'),
          end=('index',lambda x : x.max()+1),
          Values=('Values','first'))
        start  end  Values
Values                    
1           0    3     1.3
2           3    4     0.4
3           4    6     0.6
4           6    7     1.3
2 голосов
/ 03 мая 2020

Вы можете создать вспомогательную серию и группу с idxmin и idxmax:

s = a['Values'].ne(a['Values'].shift()).cumsum().rename(None)
d = dict(zip(['idxmin','idxmax'],['start','end']))

a.groupby([s,'Values'])['Values'].agg(['idxmin','idxmax']).rename(columns=d)

           start  end
  Values            
1 1.3         0    0
2 0.4         3    3
3 0.6         4    4
4 1.3         6    6

Обратите внимание, что это не дает конец как 7 для эластичного значения. 1.3, поскольку этот индекс отсутствует в кадре данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...