按时间顺序排序日期时间 (YYYY-MM-DD) 系列,精确到天级别

Chronologically sorting date time (YYYY-MM-DD) series with precision down to the level of day

我有一个 pandas 日期时间系列列(字符串格式),我想按时间顺序排序。由于原始系列已经转换为 YYYY-MM-DD 时间戳格式,如下所示:

0     1993-03-25
1     1985-06-18
2     1971-07-08
3     1975-09-27
4     2000-02-06
5     1979-07-06
6     1978-05-18
7     1989-10-24
8     1989-10-24
9     1971-04-10
10    1985-05-11
11    2011-04-09
12    1998-08-01
13    1972-01-26
14    1990-05-24

注意:这只是一小部分数据,仅供参考

我想按时间顺序对它们进行排序,精确到 'day'(年 --> 月 --> 日),并按新索引列所在的原始系列中的索引对它们进行排序每个日期时间字符串的左侧索引和原始(排序的)索引根据它们的时间顺序排列在右侧:

0     10
1     7
2     1
3     3
4     12
5     5
6     4
7     8
8     8
9     0
10    6
11    13
12    11
13    2
14    9

但是请注意,有些情况下日期时间字符串是并列的,例如,df[7]df[8] 是同一天,因此得到相同的排名 8

我已经使用 .rank(method='dense').sub(1).astype(int).sort_values(kind='mergesort') 之类的方法按年-月-日的顺序对这个日期时间系列进行排序,但似乎无法摆脱 'tied' 问题。

是否有更好的方法来解决这个并列排名问题并获得我想要的输出?

谢谢。

新编辑

我使用下面的代码生成df,.txt文件包含大量无组织的文本字符串,我使用re.findall(r' ')函数从中提取了日期时间元素。

import pandas as pd
import re  
import datetime

#load text string
doc = []
with open('dates.txt') as file:
    for line in file:
        doc.append(line)

df = pd.Series(doc)

# extract datetimes from different datetime patterns, the extracted datetime elements are in string format contained in list [] object

df['date'] = df.str.findall(r'\b....\b')

# manually replace some irregular patterns/expressions
df['date'].iloc[...] = ['10/21/79']
df['date'].iloc[...] = ['7/11/2000']
            ...
df['date'].drop('date', inplace=True)

# convert list object in each cell to string
df['date'] = df['date'].apply(lambda x: ', '.join(x))

# convert to datetime format and check for NaT cell.
df['date'] = df['date'].apply(lambda x: pd.to_datetime(x, errors='coerce'))


   
该系列每个单元格的输出格式为 YYYY-MM-DD 和 dtype = timestamp.

您可以添加一个日期作为日期时间的列 object,然后按它排序。

In [103]: df = pd.DataFrame.from_csv('t.csv', header=0, sep='\s+', index_col='id')

In [105]: df['date2'] = df.date.astype('datetime64[ns]')

In [106]: df.sort_values('date2')

Out[106]: 
          date      date2
id                       
9   1971-04-10 1971-04-10
2   1971-07-08 1971-07-08
13  1972-01-26 1972-01-26
3   1975-09-27 1975-09-27
6   1978-05-18 1978-05-18
5   1979-07-06 1979-07-06
10  1985-05-11 1985-05-11
1   1985-06-18 1985-06-18
7   1989-10-24 1989-10-24
8   1989-10-24 1989-10-24
14  1990-05-24 1990-05-24
0   1993-03-25 1993-03-25
12  1998-08-01 1998-08-01
4   2000-02-06 2000-02-06
11  2011-04-09 2011-04-09

如果要添加排名栏:

In [112]: df['sorting'] = df.sort_values('date2').index

In [113]: df.sorting
Out[113]: 
id
0      9
1      2
2     13
3      3
4      6
5      5
6     10
7      1
8      7
9      8
10    14
11     0
12    12
13     4
14    11
Name: sorting, dtype: int64

由于您的 csv 实际上没有我添加的 header 行,请执行以下操作:

In [132]: df=pd.DataFrame.from_csv('t.csv', header=None, sep='\s+')
In [133]: df[2] = df[1].astype('datetime64[ns]')
In [134]: df[3] = df.sort_values(2).index
In [135]: df[3]
Out[135]: 
0
0      9
1      2
2     13
3      3
4      6
5      5
6     10
7      1
8      7
9      8
10    14
11     0
12    12
13     4
14    11
Name: 3, dtype: int64

好的,假设它们已经是时间戳 objects 或所提供代码最后一行中定义的任何内容,您可以按原样对它们进行排序:

In [194]: df = pd.DataFrame.from_csv('dates.txt', sep='\s+')

In [195]: df['date'] = df['date'].apply(lambda x: pd.to_datetime(x, errors='coerce'
     ...: ))

In [196]: df['sorting'] = df['date'].sort_values().index

In [197]: df
Out[197]: 
         date  sorting
id                    
0  1993-03-25        9
1  1985-06-18        2
2  1971-07-08       13
3  1975-09-27        3
4  2000-02-06        6
5  1979-07-06        5
6  1978-05-18       10
7  1989-10-24        1
8  1989-10-24        7
9  1971-04-10        8
10 1985-05-11       14
11 2011-04-09        0
12 1998-08-01       12
13 1972-01-26        4
14 1990-05-24       11