我想将日期时间序列转换为季节,例如3个月,4个月,5个月我想用2(春天)替换它们;几个月6,7,8我想用3(夏天)等替换它们。
所以,我有这个系列
id
1 2011-08-20
2 2011-08-23
3 2011-08-27
4 2011-09-01
5 2011-09-05
6 2011-09-06
7 2011-09-08
8 2011-09-09
Name: timestamp, dtype: datetime64[ns]
这是我一直试图使用的代码,但无济于事。
# Get seasons
spring = range(3, 5)
summer = range(6, 8)
fall = range(9, 11)
# winter = everything else
month = temp2.dt.month
season=[]
for _ in range(len(month)):
if any(x == spring for x in month):
season.append(2) # spring
elif any(x == summer for x in month):
season.append(3) # summer
elif any(x == fall for x in month):
season.append(4) # fall
else:
season.append(1) # winter
和
for _ in range(len(month)):
if month[_] == 3 or month[_] == 4 or month[_] == 5:
season.append(2) # spring
elif month[_] == 6 or month[_] == 7 or month[_] == 8:
season.append(3) # summer
elif month[_] == 9 or month[_] == 10 or month[_] == 11:
season.append(4) # fall
else:
season.append(1) # winter
两种解决方案都不起作用,特别是在我收到错误的第一个实现中:
ValueError:具有多个元素的数组的真值 暧昧。使用a.any()或a.all()
虽然在第二个是一个有错误的大型列表。有什么想法吗?感谢
答案 0 :(得分:16)
您可以使用简单的数学公式将月份压缩到一个季节,例如:
>>> [(month%12 + 3)//3 for month in range(1, 13)]
[1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 1]
所以对于你的用例:
>>> temp2.apply(lambda dt: (dt.month%12 + 3)//3)
1 3
2 3
3 3
4 4
5 4
6 4
7 4
8 4
Name: id, dtype: int64
或者使用向量操作(credit @DSM):
>>> (temp2.dt.month%12 + 3)//3
1 3
2 3
3 3
4 4
5 4
6 4
7 4
8 4
Name: id, dtype: int64
答案 1 :(得分:2)
也可以使用字典映射。
创建一个字典,将一个月映射到一个季节:
In [27]: seasons = [1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 1]
In [28]: month_to_season = dict(zip(range(1,13), seasons))
In [29]: month_to_season
Out[29]: {1: 1, 2: 1, 3: 2, 4: 2, 5: 2, 6: 3, 7: 3, 8: 3, 9: 4, 10: 4, 11: 4, 12: 1}
使用它可以将月份转换为季节
In [30]: df.id.dt.month.map(month_to_season)
Out[30]:
1 3
2 3
3 3
4 4
5 4
6 4
7 4
8 4
Name: id, dtype: int64
性能:相当快
In [35]: %timeit df.id.dt.month.map(month_to_season)
1000 loops, best of 3: 422 µs per loop
答案 2 :(得分:1)
我认为这样可行。
AccessTimeStampParam
答案 3 :(得分:1)
我认为更精确的解决方案可能有用。如果我们有一个月 (1, ..., 12),我们可以将其转换为减一除以 3 的季节,
df = pd.Series(["2011-06-07",
"2011-08-23",
"2011-08-27",
"2011-09-01",
"2011-09-05",
"2011-09-06",
"2011-09-08",
"2011-12-25"])
df = pd.to_datetime(df)
season = (df.dt.month - 1) // 3
因此我们将 1,2,3 映射到 0(冬季),4,5,6 映射到 1(春季),7,8,9 映射到 2(夏季),以及 10,11,12到 3(秋季)。但是,我们知道 3、6、9 和 12 个月分别划分两个季节。我建议采用以下方法:
如果月份是 3 天大于等于 20,那么这个季节就是春天,我们需要求和 1。 如果月份为 6 且日大于或等于 21,则季节为夏季,我们需要求和 1。 如果月份为 9 且日大于或等于 23,则季节为秋季,我们需要求和 1。 如果月份是 3 天大于等于 20,那么这个季节就是冬天,我们需要减少 3(或者在模数 4 中和 +1)。然后我们有
season += (df.dt.month == 3)&(df.dt.day>=20)
season += (df.dt.month == 6)&(df.dt.day>=21)
season += (df.dt.month == 9)&(df.dt.day>=23)
season -= 3*((df.dt.month == 12)&(df.dt.day>=21)).astype(int)
本系列的解为 [1,2,2,2,2,2,2,0]。