Назначьте диапазоны ведер в степени 2 в отдельном столбце в пандах

У меня есть столбец значений, как показано ниже:

col
12
76
34

для которого мне нужно создать новый столбец с метками корзины для col1, как указано ниже:

col1     bucket-labels
12            8-16
76            64-128 
34            32-64

Здесь значения в столбце могут различаться, а также количество результатов.

Изменить: интервалы метки ведра должны быть в диапазоне 2 ^ n


person maninekkalapudi    schedule 15.11.2018    source источник
comment
Таким образом, интервалы всегда находятся между значениями в диапазоне 2 ^ n?   -  person yatu    schedule 15.11.2018
comment
Да, интервалы всегда находятся между значениями в диапазоне 2^n   -  person maninekkalapudi    schedule 15.11.2018


Ответы (2)


Сначала получите максимальное значение степени 2 одним из решений из здесь, создайте бины по списку, пометьте zip и передайте его < функция href="http://pandas.pydata.org/pandas-docs/stable/generated/pandas.cut.html" rel="nofollow noreferrer">cut:

import math
a = df['col'].max()
bins = [1<<exponent for exponent in range(math.ceil(math.log(a, 2))+1)]
#another solution
#bins = [1<<exponent for exponent in range((int(a)-1).bit_length() + 1)]
print (bins)
[1, 2, 4, 8, 16, 32, 64, 128]

labels = ['{}-{}'.format(i, j) for i, j in zip(bins[:-1], bins[1:])] 

df['bucket-labels'] = pd.cut(df['col'], bins=bins, labels=labels)
print (df)
   col bucket-labels
0   12          8-16
1   34         32-64
2   76        64-128
person jezrael    schedule 15.11.2018
comment
Я думаю, что создание меток может не понадобиться [pd.cut(df.col,bins).astype(str).str.slice(start=1,stop=-1).str.replace(', ','-') ] - person Naga kiran; 15.11.2018
comment
@jazreal: Спасибо за ответ, я смог получить именно те результаты, которые мне были нужны. Однако есть еще один случай, о котором я забыл упомянуть случай со значениями меньше 2, т. е. значения корзины для значений от 0 до 2. Например: если значения в col равны 0.7, диапазон корзины должен быть 0.5-1.0. Я пробовал следующее, но получил ValueError: math domain error за col value- 0.7 bins = [1<<exponent for exponent in range(math.ceil(math.log(max_col_val, min_col_val))+1)] - person maninekkalapudi; 19.11.2018
comment
@ManikanthaNekkalapudi - значит, значения между 0-2 — это несколько сегментов? как 0-0.5, 0.5-1, 1-1.5 и 1.5-2? - person jezrael; 19.11.2018
comment
Да, несколько сегментов, но это должно соответствовать моему предыдущему условию, т. Е. Диапазоны сегментов находятся в диапазоне 2 ^ n. 0.7 принадлежит (2^-1) - ((2^0)). В таком случае диапазон 1-1.5 и 1.5-2 не подходит. Полномочия 2 должны быть int - person maninekkalapudi; 19.11.2018
comment
@ManikanthaNekkalapudi - значит, необходимо добавить один бункер, например 0-1, тогда контейнеры 0,1,2,4,8,...? - person jezrael; 19.11.2018
comment
да мусорные ведра должны быть 0,1,2,4,8,.... Здесь мы рассмотрели максимальное значение как a. Можем ли мы создать другую переменную `b=df['col'].min()', чтобы она пыталась сгенерировать сегмент от самых низких до самых высоких диапазонов значений столбца? - person maninekkalapudi; 19.11.2018
comment
@ManikanthaNekkalapudi - Итак, нужно bins = [0] + [1<<exponent for exponent in range(math.ceil(math.log(a, 2)) + 1)], а затем df['bucket-labels'] = pd.cut(df['col'], bins=bins, labels=labels, include_lowest=True) - person jezrael; 19.11.2018

Используя pd.cut с 2 power контейнерами:

bins = [2**i for i in range(0,int(np.log2(df.col.max()))+2)]
#alternative [2**i for i in range(0,np.ceil(np.log2(df.col.max()))+1)]
bin_labels = [f'{x}-{y}' for x, y in zip(bins[:-1], bins[1:])]
df['bucket-labels'] = pd.cut(df.col, bins=bins, labels=bin_labels)

print(df)
   col bucket-labels
0   12          8-16
1   76        64-128
2   34         32-64
person Space Impact    schedule 15.11.2018