很抱歉,如果标题中的标题不完全清楚,但要点是我有一个熊猫DataFrame
,下面是Date
列:
Date
201611
201612
201701
我想映射它,所以我有一个period列,第一个周期的值是1,然后开始一个一个地计数直到最后一个周期,就像这样:
Date Period
201611 1
201612 2
201701 3
我实现了我想要做的:
dic_t={}
for n,t in enumerate(sorted(df.Date.unique())):
dic_t[t]=n+1
df['Period']=df.Date.map(dic_t)
但是它似乎不太pythonic。我想我可以通过字典理解来达到类似的目的,但是我还不擅长还。
有什么想法吗?
答案 0 :(得分:2)
pd.factorize
可以对项目列表进行排序并返回唯一的整数标签:
In [209]: pd.factorize(['201611','201612','201701','201702','201704','201612'], sort=True)[0]+1
Out[209]: array([1, 2, 3, 4, 5, 2])
因此您可以使用
df['Period'] = pd.factorize(df['Date'], sort=True)[0] + 1
pd.factorize
返回标签数组和唯一值数组:
In [210]: pd.factorize(['201611','201612','201701','201702','201704','201612'], sort=True)
Out[210]:
(array([0, 1, 2, 3, 4, 1]),
array(['201611', '201612', '201701', '201702', '201704'], dtype=object))
因为这个问题,看来您只想要标签,所以我使用pd.factorize(...)[0]
仅获取标签。
答案 1 :(得分:1)
因此,根据问题和评论中的信息,时段的枚举(年和月的组合)应从数据框中出现的第一个时段开始。
为此,您的代码可以正常工作。如果您认为dict
的理解看起来是“更pythonic”,则可以将其表示为:
period_dict = {
period: i+1
for i, period in enumerate(sorted(df.Date.unique()))}
df['Period'] = df.Date.map(period_dict)
请注意:使用此方法时,如果由于某种原因在开始月份之后的一个月内没有任何数据点,则该月将不会为其分配期间号。 例如,如果您没有2017年3月的数据,则:
Date Period
201611 1
201612 2
201701 3
201702 4
201704 5 <== April is period 5 and not 6
如果您需要在所有可能的期间内生成完整的枚举,请使用以下内容:
start_year = 2016
end_year = 2018
period_list = [
y*100 + m
for y in range(start_year, end_year+1)
for m in range(1, 13)]
period_dict = {
period: i+1
for i, period in enumerate(period_list)}
df['Period'] = df.Date.map(period_dict)