多谢您阅读。
首先,我将python 3.7与pandas 0.23.4和numpy 1.15结合使用。
如果我设置了df.at [(...),col] ='category'这样的类别列 效果很好。
如下例所示,如果我通过apply()函数设置类别,则该列将变为'object'dtype。
如何使用pandas中apply()函数的返回值设置类别?
<pre>
import pandas as pd
import numpy as np
phones = [5551234,5551235,5551236,5551237,5551238,5551239,5551240,5551241,5551242,5551243,5551244,5551245,5551246]
dates = ['01/01/2018','01/07/2017','01/01/2017','01/07/2016','01/01/2016','01/07/2015','01/01/2015','01/07/2014', '01/01/2014','01/07/2013','01/01/2013','01/07/2012','01/01/2012']
df = pd.DataFrame({'PHONE': phones, 'DATE': dates})
df['DATE'] = pd.to_datetime(df['DATE'], format='%d/%m/%Y', errors='coerce')
age_cats = pd.Categorical([], categories=['hot', 'warm', 'cold', 'old', 'ignored'])
df['AGE'] = pd.Series(age_cats)
df.info()
class 'pandas.core.frame.DataFrame'
RangeIndex: 13 entries, 0 to 12
Data columns (total 3 columns):
PHONE 13 non-null int64
DATE 13 non-null datetime64[ns]
AGE 0 non-null category
dtypes: category(1), datetime64[ns](1), int64(1)
memory usage: 501.0 bytes
def get_age(_date):
if pd.isnull(_date):
return 'old'
today = pd.Timestamp.today()
d = today.day
if today.month == 2 and d == 29:
d = 28
y1 = pd.Timestamp(today.year -1, today.month, d)
y2 = pd.Timestamp(today.year -2, today.month, d)
y3 = pd.Timestamp(today.year -3, today.month, d)
y4 = pd.Timestamp(today.year -4, today.month, d)
y5 = pd.Timestamp(today.year -5, today.month, d)
if today < _date:
raise Exception('Future dates mean there is a bug.')
if y1 < _date and _date <= today:
return 'hot'
elif y3 < _date and _date <= y1:
return 'warm'
elif y5 < _date and _date <= y3:
return 'cold'
else:
return 'old'
df.at[:, 'AGE'] = df.DATE.apply(get_age)
df.info()
class 'pandas.core.frame.DataFrame'
RangeIndex: 13 entries, 0 to 12
Data columns (total 3 columns):
PHONE 13 non-null int64
DATE 13 non-null datetime64[ns]
AGE 13 non-null object
dtypes: datetime64[ns](1), int64(1), object(1)
memory usage: 392.0+ bytes
</pre>
我添加了第二个AGE2列,其类别与第一列相同。 我在循环过程中使用了相同的函数,并且类别dtype没有被覆盖。
我使用apply()函数错误吗?
df['AGE2'] = pd.Series(age_cats)
for i, r in df.iterrows():
df.loc[[i],'AGE2'] = get_age(r['DATE'])
df.info()
class 'pandas.core.frame.DataFrame'
RangeIndex: 13 entries, 0 to 12
Data columns (total 4 columns):
PHONE 13 non-null int64
DATE 13 non-null datetime64[ns]
AGE 13 non-null object
AGE2 13 non-null category
dtypes: category(1), datetime64[ns](1), int64(1), object(1)
memory usage: 605.0+ bytes
答案 0 :(得分:0)
为什么不对Series
对象使用astype
来进行以下操作:
df['AGE'] = df.DATE.apply(get_age).astype('category', ordered=True, categories=['old', None])