我有以下数组(它也可以是一个列表):
uniqueDates = np.array([datetime.date(2017, 4, 11), datetime.date(2017, 4, 12),
datetime.date(2017, 4, 20), datetime.date(2017, 4, 25),
datetime.date(2017, 5, 3), datetime.date(2017, 5, 4),
datetime.date(2017, 5, 10), datetime.date(2017, 5, 11),
datetime.date(2017, 6, 1), datetime.date(2017, 6, 13),
datetime.date(2017, 6, 15), datetime.date(2017, 7, 10),
datetime.date(2017, 7, 13), datetime.date(2017, 7, 17)])
我想把这个数组分割成4个列表,每个列表包含唯一月份(四月、五月、六月和七月)中的日期。因此,预期的结果看起来像这样:
monthsList = [[datetime.date(2017, 4, 11),
datetime.date(2017, 4, 12),
datetime.date(2017, 4, 20),
datetime.date(2017, 4, 25)],
[datetime.date(2017, 5, 3),
datetime.date(2017, 5, 4),
datetime.date(2017, 5, 10),
datetime.date(2017, 5, 11)],
[datetime.date(2017, 6, 1),
datetime.date(2017, 6, 13),
datetime.date(2017, 6, 15)],
[datetime.date(2017, 7, 10),
datetime.date(2017, 7, 13),
datetime.date(2017, 7, 17)]]
我想知道是否有一个功能,可以自动做到这一点?或者我应该循环遍历元素并逐个检查它们?我正在寻找一种有效的方法来完成这项任务。我在stackoverflow中搜索了几个问题,但找不到我要找的。
只要将月份分组在一起(减少计算)就可以工作:
Dates=[]
for i in range(len(uniqueDates)):
if(Dates==[]):
Dates.append([uniqueDates[i]])
elif(uniqueDates[i].month==Dates[-1][0].month):
Dates[-1].append(uniqueDates[i])
else:
Dates.append([uniqueDates[i]])
否则使用:
Dates=[]
for i in range(len(uniqueDates)):
if(Dates==[]):
Dates.append([uniqueDates[i]])
else:
for y in range(len(Dates)):
if(Dates[y][0].month == uniqueDates[i].month):
Dates[y].append(uniqueDates[i])
break
if(y==len(Dates)-1):
Dates.append([uniqueDates[i]])
两输出:[
[datetime.date(2017, 4, 11), datetime.date(2017, 4, 12), datetime.date(2017, 4, 20), datetime.date(2017, 4, 25)],
[datetime.date(2017, 5, 3), datetime.date(2017, 5, 4), datetime.date(2017, 5, 10), datetime.date(2017, 5, 11)],
[datetime.date(2017, 6, 1), datetime.date(2017, 6, 13), datetime.date(2017, 6, 15)],
[datetime.date(2017, 7, 10), datetime.date(2017, 7, 13), datetime.date(2017, 7, 17)]
]
计时第一个和第二个函数的结果以及@Tom83B提供的熊猫答案:
Repeated: 100,000x
First Function: 0.10295674900044105 seconds
Second Function: 1.5613631390006049 seconds
Pandas Function: 146.28389169599905 seconds
您可以使用pandas:
import pandas as pd
...
s = pd.Series(uniqueDates)
list(s.groupby(s.map(lambda x: x.month)))
编辑:正如Nidal Barada所指出的,他的循环方法明显更快。在Jupyter中使用%%timeit魔法:
pandas: 562µs±3.87µs/loop(平均值±std. dev. of 7次运行,每次1000个循环)
Nidal Barada的答案:每循环8.14µs±39.9 ns(7次运行的平均值±标准差,每次100000次循环)
你可以在itertools中使用groupby:
from itertools import groupby
grouped = [[*g] for _,g in groupby(uniqueDates,key=lambda d:(d.year,d.month))]
print(*(", ".join(map(str,g)) for g in grouped),sep="n")
2017-04-11, 2017-04-12, 2017-04-20, 2017-04-25
2017-05-03, 2017-05-04, 2017-05-10, 2017-05-11
2017-06-01, 2017-06-13, 2017-06-15
2017-07-10, 2017-07-13, 2017-07-17
即使你的输入只是一个普通的Python列表,这也可以工作。除非必要,否则不要使用numpy