如何从熊猫数据框中的字符串中提取最后一个日期

时间:2019-04-20 13:48:56

标签: python pandas list csv dataframe

我需要为熊猫数据框中的每一行查找字符串中特定文本之前的最后日期。文本可以在字符串中日期之后的任意位置。

我有一个由两列组成的csv文件。第一个是参考号(每行唯一),另一个是可以用逗号分隔的字符串。与此类似:

Ref No  Audit
abc123  "text1, text2, text3"
abc124  "text1, text2, text3"

Ref No是指数据库中的某个项目,“审核”是对该项目所做的所有更改的审核。文本中每个逗号分隔的项目都是单个更改(例如,text1是更改,text2是更改等)。仅当在新日期上进行更改时,日期才被附加到文本部分的开头。 “审核”列中的每个项目如下所示:

“ 01/01/2019 09:15:12任务1已完成,任务2已完成,任务3已完成,02/01/2019 15:26:03任务4已完成,任务5已完成”。

我正在尝试寻找一种方法来识别特定任务的完成时间。在上面的示例中,如果我想知道任务5何时完成,那就是02/01/2019。

除了将数据放入熊猫数据框并将“审核”文本放入列表之外,我对如何执行此操作也一无所知。

import pandas as pd

audit = pd.read_csv('audit_export1.csv', encoding='latin1')

audit['Audit'].apply(pd.Series)
audit['Audit'] = audit['Audit'].str.split(',')

我希望得到一个包含2列的数据框;搜索的参考和更改日期。

对于我在措辞上出现的任何错误或明显错误,我们深表歉意,我对python很陌生,因此非常感谢您能提供的任何帮助。我查看了以前问过的问题,但找不到任何能解决该问题的信息,但这可能是由于我缺乏知识而无法归纳指导。

编辑

27/03/2019 09:34:41 Jo​​hn Smith字段“ Handler”已从旧值“”更改为新值“ John Doe”,字段“ Workflow Status”已从旧值“ Awaiting”更改分配”到新值“ With Handler”,27/03/2019 22:24:19 Jane Doe字段“ Handler”已从旧值“ Jane Doe”更改为新值“ Bill Smith”,2019/10/04 04:58:43 Jill Smith字段“ Workflow Status”已从旧值“ With Handler”更改为新值“ Passed to Clearing Desk”,10/04/2019 06:31:09 Sam Jones字段“ Workflow Status” “已从旧值” Passed to Clearing Desk“更改为新值” QC“,13/04/2019 08:30:49 Dave Jones字段” QC Handler“已从旧值”“更改为新值” Dave Jones”,字段“工作流状态”已从旧值“ QC”更改为新值“ QC-With Handler”,13/04/2019 09:06:36 Dave Jones字段“工作流状态”已更改从旧值“ QC-带处理程序”到新值“传递回返工”,17/04/2019 2 3:52:11 Sally Smith字段“工作流状态”已从旧值“传递回返工”更改为新值“ QC-传递给清算台”,18/04/2019 2:45:30 Bill Jones,“工作流状态”字段已从旧值“ QC-Passed to Clearing Desk”更改为新值“投诉处理”

编辑2

import pandas as pd
import re
a = pd.read_csv('audit_export1.csv')
to_find = "Workflow Status"

for cases in a:
    date_list = re.findall(r'\d+/\d+/\d+ \d+:\d+:\d+ ', a['Audit Trail'])

    s = re.split(r'\d+/\d+/\d+ \d+:\d+:\d+ ', a['Audit Trail'])
    task_list = [i for i in s if i != '']

    for  i, item in enumerate(task_list):
        if to_find in item:
            a['Audit Date'] = date_list[i]

编辑3

import pandas as pd
from datetime import datetime

to_find = 'Workflow'
a = pd.read_csv('audit_export2.csv')

a.Audit = a.Audit.str.split(',')

overall_list = []
for tmplist in a.Audit:
    dl = []
    for i in tmplist:
        i = i.strip()
        try: 
            sdate = datetime.strptime(i[:10],'%d/%m/%Y')
            dl.append(str(sdate) + i[10:])
        except ValueError: # if its NOT a date, adding the date got from the try block to the string
            dl.append(str(sdate) + i)
        dl = dl[::-1]
    overall_list.append(dl)

a['Audit_date'] = pd.Series(overall_list)

2 个答案:

答案 0 :(得分:0)

这不是完整的代码,它只是为您提供了一个入门指南,您还需要进行一些检查以适应其他可能性

如果您的数据格式一致,则有很多选择

当您从csv文件加载条目时,每个条目都将看起来像以下“ 02/01/2019 15:26:03任务4完成”,您可以像这样简单地处理此字符串

text = "02/01/2019 15:26:03 task 4 completed"
i = text.index('task')
print(text[i:])
print(text[:i-1])

输出:

task 4 completed
02/01/2019 15:26:03

或者如您所说,如果您的日期格式始终相同,则可以直接使用索引:

print(text[20:])
print(text[:20])

编辑:要针对特定​​情况工作,并且一个以上日期存在多个任务,请参见以下内容:

我们将使用正则表达式在每个日期发生时拆分文本并将任务存储在任务列表中,并找到所有日期并将其放在其他列表中,然后剩下的将很容易

text = "01/01/2019 09:15:12 task 1 completed, task 2 completed, task 3 completed, 02/01/2019 15:26:03 task 4 completed, task 5 completed"

import re
def get_date(task):
    date_list = re.findall(r'\d+/\d+/\d+ \d+:\d+:\d+ ', text)

    s = re.split(r'\d+/\d+/\d+ \d+:\d+:\d+ ', text)
    task_list = [i for i in s if i != '']

    for  i, item in enumerate(task_list):
        if task in item:
            return date_list[i]

进行测试

my_task = 'task 5'
result = get_date(my_task)
print(my_task, 'completed on', result)

输出:

task 5 completed on 02/01/2019 15:26:03 

答案 1 :(得分:0)

严格在您感兴趣的日期的前提下,将其放在第一部分,并且每行的第一行文本中始终会有一个日期,将产生以下代码

import pandas as pd
from datetime import datetime

a = pd.read_csv('audit_export1.csv')

a.Audit = a.Audit.str.split(',')

overall_list = []
for tmplist in a.Audit:
    dl = []
    for i in tmplist:
        i = i.strip()
        try: 
            sdate = datetime.strptime(i[:19],'%d/%m/%Y %H:%M:%S')
            dl.append(str(sdate) + i[19:])
        except ValueError: # if its NOT a date, adding the date got from the try block to the string
            dl.append(str(sdate) + i)
    overall_list.append(dl)

a['Audit_date'] = pd.Series(overall_list)

我试图在那些没有日期部分的字符串中复制日期部分,并创建了一个新列,并在字符串的开头插入了日期。您可以根据需要使用结果列表。例如,输出将如下所示

print(a.Audit_date[0])

['2019-01-01 09:15:12 task 1 completed',
 '2019-01-01 09:15:12task 2 completed',
 '2019-01-01 09:15:12task 3 completed',
 '2019-01-02 15:26:03 task 4 completed',
 '2019-01-02 15:26:03task 5 completed']