python - 如何使用IntervalIndex生成.cat.codes

标签 python pandas dataframe categories categorical-data

我有一个数据集,我将qcut并将其形成类别为pandas.core.indexes.interval.IntervalIndex

如何使用从原始数据集生成的相同类别对 future 数据集进行分类?

解释代码:

>>> import pandas as pd
>>> import numpy as np
>>> np.random.seed(42)

>>> df = pd.DataFrame(np.random.randint(0,100,size=(10, 4)), columns=list('ABCD'))

>>> df
    A   B   C   D
 0  51  92  14  71
 1  60  20  82  86
 2  74  74  87  99
 3  23  2   21  52
 4  1   87  29  37
 5  1   63  59  20
 6  32  75  57  21
 7  88  48  90  58
 8  41  91  59  79
 9  14  61  61  46

>>> categories_a = pd.qcut(df['A'], 4).cat.categories

>>> type(categories_a)
pandas.core.indexes.interval.IntervalIndex

>>> categories_a
IntervalIndex([(0.999, 16.25], (16.25, 36.5], (36.5, 57.75], (57.75, 88.0]]
          closed='right',
          dtype='interval[float64]')

我尝试过的:

我尝试使用CategoricalDtypedf['B'].astype(categories_a)之类的东西,但没有成功。对于如何以优雅的方式做到这一点,我已经没有想法了。

预期结果:

鉴于 dfcategories_a 与上面相同,我想根据 df['B'] 转换所有元素到 .cat.codes 作为由 pd.qcut(df['A'], 4).cat.codes 生成的代码。输出如下:

df['B'] 
original --> processed # comment
92 --> 3 # (57.75, 88.0] this one actually goes through the roof
20 --> 1 # (16.25, 36.5]
74 --> 3 # (57.75, 88.0]
2  --> 0 # (0.999, 16.25]
87 --> 3 # (57.75, 88.0]
63 --> 3 # (57.75, 88.0]
75 --> 3 # (57.75, 88.0]
48 --> 2 # (36.5, 57.75]
91 --> 3 # (57.75, 88.0]
61 --> 3 # (57.75, 88.0]

我希望这足够清楚。

最佳答案

使用与上面相同的逻辑,但要获取处理后的数据框中的类别而不是范围:

np.random.seed(42)
df = pd.DataFrame(np.random.randint(0,100,size=(10, 4)), columns=list('ABCD'))


series, bins = pd.qcut(df["A"], 4, retbins=True, labels=False)
def apply_cut(df):
    for i in df.columns:
        df[i] = pd.cut(df[i], bins=bins, labels=False, include_lowest=True)
    return df

processed = apply_cut(df)

返回:

>>> processed
   A    B    C    D
0  2  NaN  0.0  3.0
1  3  1.0  3.0  3.0
2  3  3.0  3.0  NaN
3  1  0.0  1.0  2.0
4  0  3.0  1.0  2.0
5  0  3.0  3.0  1.0
6  1  3.0  2.0  1.0
7  3  2.0  NaN  3.0
8  2  NaN  3.0  3.0
9  0  3.0  3.0  2.0

如果您想摆脱 NaN 并将它们强制放入最接近的类别,您可以执行相同的操作,但添加 -float(np.inf)float( np.inf) 到第一个和最后一个 bin:

series, bins = pd.qcut(df["A"], 4, retbins=True, labels=False)
bins[0] = -float(np.inf)
bins[-1] = float(np.inf)
def apply_cut(df):
    for i in df.columns:
        df[i] = pd.cut(df[i], bins=bins, labels=False, include_lowest=True,right=False)
    return df

processed = apply_cut(df)

>>> processed
   A  B  C  D
0  2  3  0  3
1  3  1  3  3
2  3  3  3  3
3  1  0  1  2
4  0  3  1  2
5  0  3  3  1
6  1  3  2  1
7  3  2  3  3
8  2  3  3  3
9  0  3  3  2

piR 编辑

请根据您的需要删除/更改。这是你的帖子,我打扰了 (-:

bins = pd.qcut(df.A, 4, retbins=True)[1]
bins[0] -= np.finfo(np.float).resolution

df.apply(lambda c: pd.cut(c, bins))

               A              B              C              D
0  (36.5, 57.75]            NaN   (1.0, 16.25]  (57.75, 88.0]
1  (57.75, 88.0]  (16.25, 36.5]  (57.75, 88.0]  (57.75, 88.0]
2  (57.75, 88.0]  (57.75, 88.0]  (57.75, 88.0]            NaN
3  (16.25, 36.5]   (1.0, 16.25]  (16.25, 36.5]  (36.5, 57.75]
4   (1.0, 16.25]  (57.75, 88.0]  (16.25, 36.5]  (36.5, 57.75]
5   (1.0, 16.25]  (57.75, 88.0]  (57.75, 88.0]  (16.25, 36.5]
6  (16.25, 36.5]  (57.75, 88.0]  (36.5, 57.75]  (16.25, 36.5]
7  (57.75, 88.0]  (36.5, 57.75]            NaN  (57.75, 88.0]
8  (36.5, 57.75]            NaN  (57.75, 88.0]  (57.75, 88.0]
9   (1.0, 16.25]  (57.75, 88.0]  (57.75, 88.0]  (36.5, 57.75]

或者:

bins = pd.qcut(df.A, 4, retbins=True)[1]
bins[0] = -float(np.inf)
bins[-1] = float(np.inf)

processed = df.apply(lambda c: pd.cut(c, bins, labels=False))

>>> processed
   A  B  C  D
0  2  3  0  3
1  3  1  3  3
2  3  3  3  3
3  1  0  1  2
4  0  3  1  2
5  0  3  3  1
6  1  3  2  1
7  3  2  3  3
8  2  3  3  3
9  0  3  3  2

关于python - 如何使用IntervalIndex生成.cat.codes,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49265724/

相关文章:

python - 对 Pandas Dataframe 列中的列表进行排序

python - 对数据帧列表执行操作

r - 在单列数据框上使用 order

r - 有效地计算跨多列的字符串出现次数

python - 在 scikit learn 中保存并重用 TfidfVectorizer

Python 对象@property

python - groupby - python Pandas 数据框

python - TensorFlow Iris load_csv_with_header( )

python - 围绕未指定的任何字符拆分字符串

python - 从前两组中获取前两行