Вернуть нижнюю или верхнюю границу диапазона после биннинга в Python - PullRequest
2 голосов
/ 17 марта 2020

Я преобразую следующие значения df в контейнеры, используя pd.cut следующим образом:

import numpy as np
import pandas as pd
df = pd.DataFrame(np.random.randint(0,100,size=(5, 4)), columns=list('ABCD'))
print(df)
newDF = pd.cut(df.A, 2, precision=0)
print(newDF)

A   B   C   D
0  83  43  99  85
1   6  57  44  45
2   5  72  10  53
3  24  50  23  18
4  75  25  96  27
0    (44.0, 83.0]
1     (5.0, 44.0]
2     (5.0, 44.0]
3     (5.0, 44.0]
4    (44.0, 83.0]

Есть ли способ вернуть нижнюю границу или верхнюю границу диапазона вместо всего диапазона? Например, из приведенного выше примера:

0    44.0
1    5.0
2    5.0
3    5.0
4    44.0

Ответы [ 3 ]

3 голосов
/ 17 марта 2020

Для числовых значений, если вы передадите константу bins, pd.cut будет просто вырезано для np.linspace(min,max, bins+1). Итак

bins = 2
interval_bins = np.linspace(df.A.min(), df.A.max(),bins+1)

lefts = interval_bins[:-1]
rights = inteval_bins[1:]
3 голосов
/ 17 марта 2020

Использование Series.map:

pd.cut(df.A, 2, precision=0).map(lambda x: x.left)

или pd.IntervalIndex

s = pd.cut(df.A, 2, precision=0)
pd.Series(data=pd.IntervalIndex(s).left, index = s.index)

#print(df)
#
#
#    A   B   C   D
#0  26  70  28   2
#1  49  42  56  28
#2  48  26  40  19
#3   3  50  17   3
#4  20  34  54  42
#
#
#pd.cut(df.A, 2, precision=0).map(lambda x: x.left)
#
#0     3.0
#1    26.0
#2    26.0
#3     3.0
#4     3.0
#Name: A, dtype: category
#Categories (2, float64): [3.0 < 26.0]
0 голосов
/ 17 марта 2020

Это не слишком отличается от ответа @ ansev. Тем не менее, я действительно хотел IntervalDtype аксессор для pd.Series объектов, чтобы такие вещи работали.

# THIS IS NOT REAL!
# JUST AN EXAMPLE
# OF WHAT I WANT
newDF.astype(pd.IntervalDtype()).interval.left

Итак, в поисках такой вещи, я наткнулся на то же, что и @ ansev. Я ожидаю, что это изменится в будущем. Я подозреваю, что они добавят IntervalDtype аксессор (возможно).

Я предложу простое понимание списка. Это предложение представляет собой простое решение без создания дополнительных pandas объектов.

cats = newDF.cat.categories
codes = newDF.cat.codes
pd.Series([cats[code].left for code in codes], newDF.index)

0    54.0
1    54.0
2    14.0
3    14.0
4    54.0
dtype: float64
...