Python Pandas从时间序列中提取唯一日期

30

我有一个包含大量盘中数据的DataFrame,其中包含几天的数据,日期不连续。

 2012-10-08 07:12:22            0.0    0          0  2315.6    0     0.0    0
 2012-10-08 09:14:00         2306.4   20  326586240  2306.4  472  2306.8    4
 2012-10-08 09:15:00         2306.8   34  249805440  2306.8  361  2308.0   26
 2012-10-08 09:15:01         2308.0    1   53309040  2307.4   77  2308.6    9
 2012-10-08 09:15:01.500000  2308.2    1  124630140  2307.0  180  2308.4    1
 2012-10-08 09:15:02         2307.0    5   85846260  2308.2  124  2308.0    9
 2012-10-08 09:15:02.500000  2307.0    3  128073540  2307.0  185  2307.6   11
 ......
 2012-10-10 07:19:30            0.0    0          0  2276.6    0     0.0    0
 2012-10-10 09:14:00         2283.2   80   98634240  2283.2  144  2283.4    1
 2012-10-10 09:15:00         2285.2   18  126814260  2285.2  185  2285.6    3
 2012-10-10 09:15:01         2285.8    6   98719560  2286.8  144  2287.0   25
 2012-10-10 09:15:01.500000  2287.0   36  144759420  2288.8  211  2289.0    4
 2012-10-10 09:15:02         2287.4    6  109829280  2287.4  160  2288.6    5
 ......

如何从上面的DataFrame中提取日期时间格式的唯一日期?结果应该像这样:[2012-10-08, 2012-10-10]

4个回答

51
如果您有一个类似于Series的数据结构:
In [116]: df["Date"]
Out[116]: 
0           2012-10-08 07:12:22
1           2012-10-08 09:14:00
2           2012-10-08 09:15:00
3           2012-10-08 09:15:01
4    2012-10-08 09:15:01.500000
5           2012-10-08 09:15:02
6    2012-10-08 09:15:02.500000
7           2012-10-10 07:19:30
8           2012-10-10 09:14:00
9           2012-10-10 09:15:00
10          2012-10-10 09:15:01
11   2012-10-10 09:15:01.500000
12          2012-10-10 09:15:02
Name: Date

每个对象都是一个时间戳

In [117]: df["Date"][0]
Out[117]: <Timestamp: 2012-10-08 07:12:22>

通过调用.date(),您只能获取日期:

In [118]: df["Date"][0].date()
Out[118]: datetime.date(2012, 10, 8)

Series和DataFrame都有一个.unique()方法。 因此你可以使用maplambda

In [126]: df["Date"].map(lambda t: t.date()).unique()
Out[126]: array([2012-10-08, 2012-10-10], dtype=object)

或者使用Timestamp.date方法:

In [127]: df["Date"].map(pd.Timestamp.date).unique()
Out[127]: array([2012-10-08, 2012-10-10], dtype=object)

谢谢,不过我还有一个问题,如果我将“日期”列设置为索引,那么df.index.map(pd.Timestamp.date).unique()会抛出“'numpy.ndarray' object has no attribute 'unique'”错误。 - tesla1060
2
@tesla1060:你可以将它推回到一个Series中,使用pd.Series(df.index).map等。或者如果顺序无关紧要,甚至可以使用set(df.index.map(pd.Timestamp.date)) - DSM
请注意,.unique() 会将值的类型悄悄地更改为“numpy.datetime64”。 - quant_dev
列表推导式更快。例如,在大约2000个日期的情况下:%timeit df.index.map(pd.Timestamp.date).unique()给出了53.7毫秒,而%timeit pd.Series([d.date() for d in df.index]).unique()则只用了4.9毫秒 - Daniel Goldfarb

4

为了给@DSM提供另一种答案的选择,可以看看@Psidom的其他答案

代码应该是这样的:

pd.to_datetime(df['DateTime']).dt.date.unique()

在我看来,它的表现稍微好一些。


为了使您的答案更完整,请添加显示性能改进的输出。 - Walter_Ritzel

2

使用正则表达式:

(\d{4}-\d{2}-\d{2})

使用re.findall函数运行它,以获取所有匹配项:

result = re.findall(r"(\d{4}-\d{2}-\d{2})", subject)

2
这是我在Python 3.6.8和Pandas 1.1.5上得到的结果:
%timeit df['date'].map(lambda d: d.date()).unique()

2.06 ms ± 135 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit df['date'].dt.date.unique()

535 µs ± 79.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%timeit df['date'].dt.normalize().unique()

1.33 ms ± 229 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)
normalize().unique() 的输出结果如下:
array(['2021-04-08T00:00:00.000000000', '2021-04-07T00:00:00.000000000',
       '2021-04-06T00:00:00.000000000', '2021-04-05T00:00:00.000000000',
       '2021-04-04T00:00:00.000000000', '2021-04-03T00:00:00.000000000',
       '2021-04-02T00:00:00.000000000', '2021-04-01T00:00:00.000000000',
       ..., dtype='datetime64[ns]')

与另外两个的输出进行比较:
array([datetime.date(2021, 4, 8), datetime.date(2021, 4, 7),
       datetime.date(2021, 4, 6), datetime.date(2021, 4, 5),
       datetime.date(2021, 4, 4), datetime.date(2021, 4, 3),
       datetime.date(2021, 4, 2), datetime.date(2021, 4, 1),
       datetime.date(2021, 3, 31), datetime.date(2021, 3, 30),
       ..., dtype=object)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接