如何将数字数据映射到Pandas数据帧中的类别/分类

时间:2018-03-20 10:48:24

标签: python python-2.7 pandas numpy dataframe

我刚刚开始使用python进行编码,而且我的一般编码技巧相当生疏:(所以请耐心等待

我有一个pandas数据帧:

SamplePandas

它有大约3米的行。有3种age_units:Y,D,W多年,Days&amp;周。任何超过1岁的人都有一个年龄单位为Y,我想要的第一个分组是<2岁,所以我必须在年龄单位进行测试才是Y ...

我想创建一个新的AgeRange列并填充以下范围:

  • &lt; 2
  • 2 - 18
  • 18 - 35
  • 35 - 65
  • 65 +

所以我写了一个函数

def agerange(values):
    for i in values:
        if complete.Age_units == 'Y':
            if complete.Age > 1 AND < 18 return '2-18'
            elif complete.Age > 17 AND < 35 return '18-35'
            elif complete.Age > 34 AND < 65 return '35-65'
            elif complete.Age > 64 return '65+'
        else return '< 2'

我想如果我把整个数据框作为一个整体传入,我会得到我需要的东西,然后可以创建我想要的这样的列:

agedetails['age_range'] = ageRange(agedetails)

但是当我尝试运行第一个代码来创建我得到的函数时:

  File "<ipython-input-124-cf39c7ce66d9>", line 4
    if complete.Age > 1 AND complete.Age < 18 return '2-18'
                          ^
SyntaxError: invalid syntax

显然它不接受AND - 但我认为我在课堂上听到过我可以使用AND这样吗?我必须弄错,但那么这样做的正确方法是什么?

因此,在得到该错误之后,我甚至不确定传入数据帧的方法也会引发错误。我猜可能是的。在这种情况下 - 我如何才能完成这项工作?

我希望学习最好的方法,但对我来说最好的方法之一就是保持简单,即使这意味着要做几件事......

1 个答案:

答案 0 :(得分:18)

使用Pandas,您应该避免逐行操作,因为这些操作通常涉及低效的Python级循环。以下是几种选择。

熊猫:pd.cut

正如@JonClements建议的那样,您可以使用pd.cut,这样做的好处是您的新列变为Categorical

您只需要定义边界(包括np.inf)和类别名称,然后将pd.cut应用于所需的数字列。

bins = [0, 2, 18, 35, 65, np.inf]
names = ['<2', '2-18', '18-35', '35-65', '65+']

df['AgeRange'] = pd.cut(df['Age'], bins, labels=names)

print(df.dtypes)

# Age             int64
# Age_units      object
# AgeRange     category
# dtype: object

NumPy:np.digitize

np.digitize提供了另一种清洁解决方案。我们的想法是定义您的边界和名称,创建字典,然后将np.digitize应用于您的年龄列。最后,使用您的字典来映射您的类别名称。

请注意,对于边界情况,下限用于映射到bin。

import pandas as pd, numpy as np

df = pd.DataFrame({'Age': [99, 53, 71, 84, 84],
                   'Age_units': ['Y', 'Y', 'Y', 'Y', 'Y']})

bins = [0, 2, 18, 35, 65]
names = ['<2', '2-18', '18-35', '35-65', '65+']

d = dict(enumerate(names, 1))

df['AgeRange'] = np.vectorize(d.get)(np.digitize(df['Age'], bins))

结果

   Age Age_units AgeRange
0   99         Y      65+
1   53         Y    35-65
2   71         Y      65+
3   84         Y      65+
4   84         Y      65+