【问题标题】:Chronologically sorting date time (YYYY-MM-DD) series with precision down to the level of day按时间顺序排序的日期时间 (YYYY-MM-DD) 系列,精确到日级别
【发布时间】:2017-08-08 16:53:34
【问题描述】:

我有一个 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

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

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

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') 之类的方法按年月日顺序对这个日期时间序列进行排序,但似乎无法摆脱“捆绑”问题。

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

谢谢。

新编辑

我使用以下代码生成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。

【问题讨论】:

  • 您的日期实际上是日期时间,还是格式不错的字符串?
  • 它们是字符串。我将在线程上编辑此信息。
  • 如果它们在 YYYY-MM-DD 中,你不能按字典顺序排序吗?
  • 如何按字典顺序对它们进行排序?如果有人能就此启发我,将不胜感激。

标签: python sorting datetime series rank


【解决方案1】:

您可以添加一个包含日期的列作为日期时间对象,然后按此排序。

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 实际上没有我添加的标题行,因此请执行以下操作:

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

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

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

【讨论】:

  • 感谢您的回复。它给出了一条错误消息,说命令行 'df['date2'] = df.date.astype('datetime64[ns]')' 只能加入可迭代
  • 您的 CSV 是否与您在帖子中提供的数据一模一样?
  • 是的,它们是使用 'pd.to_datetime()' 创建的
  • 好的,我在帖子末尾添加了一个示例,没有适合我的标题。
  • 您好,这种语法“df[1]astype('datetime64[ns]')”不适用于我的编辑器。我怀疑这是因为我的熊猫系列被命名为 df['date'] (但它没有像您使用的那样的标题),将 astype('datetime64[ns]') 放在它产生错误之后。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-07-20
  • 1970-01-01
  • 1970-01-01
  • 2013-10-19
  • 2014-11-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多