Python Pandas Создать новую переменную Bin/Bucket с помощью pd.qcut

Как вы создаете новую переменную Bin/Bucket с помощью pd.qut в python?

Это может показаться элементарным для опытных пользователей, но я не был предельно ясен в этом, и было удивительно неинтуитивно, чтобы искать в переполнении стека /google. Некоторый тщательный поиск дал это (Назначение qcut как новый столбец), но он не совсем ответил на мой вопрос, потому что он не сделал последнего шага и не помещал все в бункеры (т.е. 1,2,...).

Ответ 1

РЕДАКТИРОВАТЬ: Нижеприведенный ответ действителен только для версий Pandas менее 0,15.0. Если вы используете Pandas 15 или выше, см.

data3['bins_spd'] = pd.qcut(data3['spd_pct'], 5, labels=False)

Спасибо @unutbu за указание на это.:)

Скажите, что у вас есть данные, которые вы хотите использовать в bin, в моем случае варианты спреды, и вы хотите создать новую переменную с ведрами, соответствующими каждому наблюдению. Ссылка, упомянутая выше, вы можете сделать это:

print pd.qcut(data3['spd_pct'], 40)

(0.087, 0.146]
(0.0548, 0.087]
(0.146, 0.5]
(0.146, 0.5]
(0.087, 0.146]
(0.0548, 0.087]
(0.5, 2]

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

print pd.qcut(data3['spd_pct'],5).labels

[2 1 3 ..., 0 1 4] 

Объединяя все вместе, если вы хотите создать новую переменную только с номерами ящиков, этого должно быть достаточно:

data3['bins_spd']=pd.qcut(data3['spd_pct'],5).labels

print data3.head()

   secid      date    symbol  symbol_flag     exdate   last_date cp_flag  0   5005  1/2/1997  099F2.37            0  1/18/1997         NaN       P   
1   5005  1/2/1997  09B0B.1B            0  2/22/1997   12/3/1996       P   
2   5005  1/2/1997  09B7C.2F            0  2/22/1997  12/11/1996       P   
3   5005  1/2/1997  09EE6.6E            0  1/18/1997  12/27/1996       C   
4   5005  1/2/1997  09F2F.CE            0  8/16/1997         NaN       P   

   strike_price  best_bid  best_offer     ...      close  volume_y    return  0          7500     2.875      3.2500     ...        4.5     99200  0.074627   
1         10000     5.375      5.7500     ...        4.5     99200  0.074627   
2          5000     0.625      0.8750     ...        4.5     99200  0.074627   
3          5000     0.125      0.1875     ...        4.5     99200  0.074627   
4          7500     3.000      3.3750     ...        4.5     99200  0.074627   

   cfadj_y  open  cfret  shrout      mid   spd_pct  bins_spd  
0        1   4.5      1   57735  3.06250  0.122449         2  
1        1   4.5      1   57735  5.56250  0.067416         1  
2        1   4.5      1   57735  0.75000  0.333333         3  
3        1   4.5      1   57735  0.15625  0.400000         3  
4        1   4.5      1   57735  3.18750  0.117647         2  

[5 rows x 35 columns]

Надеюсь, это поможет кому-то другому. По крайней мере, это должно быть проще искать сейчас.:)

Ответ 2

В Pandas 0.15.0 или новее pd.qcut вернет Серию, а не Категорию, если вход представляет собой Серию ( как есть, в вашем случае), или если labels=False. Если вы установите labels=False, то qcut вернет серию с целыми индикаторами бункеров в качестве значений.

Таким образом, чтобы обеспечить будущий код, вы можете использовать

data3['bins_spd'] = pd.qcut(data3['spd_pct'], 5, labels=False)

или, передайте массив NumPy в pd.qcut, чтобы получить категориальное значение в качестве возвращаемого значения. Обратите внимание, что категориальный атрибут labels устарел. Вместо этого используйте codes:

data3['bins_spd'] = pd.qcut(data3['spd_pct'].values, 5).codes