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

kil*_*nen 8 python numpy dataframe python-2.7 pandas

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

我有一个pandas数据帧:

SamplePandas

它有大约3米的行.age_units有3种:Y,D,W年,日和周.任何1岁以上的人的年龄单位都是Y,我想要的第一个分组是<2岁,所以我需要在年龄单位进行测试才是Y ...

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

  • <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'
Run Code Online (Sandbox Code Playgroud)

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

agedetails['age_range'] = ageRange(agedetails)
Run Code Online (Sandbox Code Playgroud)

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

  File "<ipython-input-124-cf39c7ce66d9>", line 4
    if complete.Age > 1 AND complete.Age < 18 return '2-18'
                          ^
SyntaxError: invalid syntax
Run Code Online (Sandbox Code Playgroud)

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

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

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

jpp*_*jpp 25

使用Pandas,您应该避免逐行操作,因为这些操作通常涉及低效的Python级循环.这里有几个选择.

熊猫: pd.cut

正如@JonClements建议的那样,你可以使用pd.cut这个,这里的好处是你的新列成为一个分类.

您只需要定义边界(包括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
Run Code Online (Sandbox Code Playgroud)

NumPy的: np.digitize

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

请注意,对于边界情况,下限用于映射到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))
Run Code Online (Sandbox Code Playgroud)

结果

   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+
Run Code Online (Sandbox Code Playgroud)

  • 或者......将`float('inf')`(或`np.inf`)添加到`bins`的末尾,然后使用:`pd.cut(df.Age,bins,labels = names)`. ..那样你就会得到一个绝对的系列而不是一个字符串...... (2认同)