我刚刚开始使用python进行编码,而且我的一般编码技巧相当生疏:(所以请耐心等待
我有一个pandas数据帧:
它有大约3米的行。有3种age_units:Y,D,W多年,Days&amp;周。任何超过1岁的人都有一个年龄单位为Y,我想要的第一个分组是<2岁,所以我必须在年龄单位进行测试才是Y ...
我想创建一个新的AgeRange列并填充以下范围:
所以我写了一个函数
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这样吗?我必须弄错,但那么这样做的正确方法是什么?
因此,在得到该错误之后,我甚至不确定传入数据帧的方法也会引发错误。我猜可能是的。在这种情况下 - 我如何才能完成这项工作?
我希望学习最好的方法,但对我来说最好的方法之一就是保持简单,即使这意味着要做几件事......
答案 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
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+