使用Python/Pandas从正文中解析出特定文本的有效方法

使用Python/Pandas从正文中解析出特定文本的有效方法,python,pandas,Python,Pandas,我有一个大约有3000行的电子表格,我想使用Python和pandas对其进行迭代。我已经弄明白了除了有效地解析其中一个单元格中的一些文本之外,如何做所有事情。3000条记录中的每一条都有一个单元格,看起来像: -- Status Change:01/09/2017 9:32:13 AM, C K:: Status = Ready to be fit -- Status Change:19/09/2017 7:53:28 AM, C K:: Status = Complete -- Status

我有一个大约有3000行的电子表格,我想使用Python和pandas对其进行迭代。我已经弄明白了除了有效地解析其中一个单元格中的一些文本之外,如何做所有事情。3000条记录中的每一条都有一个单元格,看起来像:

-- Status Change:01/09/2017 9:32:13 AM, C K:: Status = Ready to be fit
-- Status Change:19/09/2017 7:53:28 AM, C K:: Status = Complete
-- Status Change:29/08/2017 8:20:04 AM, C K:: Status = Ready to Schedule
-- Assigned To Change:29/08/2017 8:19:53 AM, C K:: Assigned To Joe   Blow
-- Status Change:29/08/2017 8:19:53 AM, C K:: Status = Scheduled
-- Status Change:22/08/2017 8:33:38 AM, C K:: Status = Sent
-- Assigned To Change:22/08/2017 8:32:46 AM, C K:: Assigned To John   Doe
-- Status Change:17/08/2017 1:52:07 PM, C K:: Status = Ready to Pull Plastic
 Started by Joe   Blow at Winnipeg on 15/08/2017 11:20:56 AM:: Assigned To Joe   Blow
在这篇庞大的正文中,我唯一关心的是它的位置——状态更改:19/09/2017 7:53:28 AM,C K::Status=Complete

我希望能够提取此任务完成的日期

所以我的解决方案是:

        completeIndex = string.find('Complete')
        dateStart = completeIndex-38
        dateEnd = dateStart+8
        date = string[dateStart:dateEnd]
        print(date)
于2017年9月19日发布

这很好,但速度很慢。有没有更具蟒蛇风格或更好的方法来利用熊猫更有效地做到这一点


谢谢

假设s是字符串,类似的方法应该可以工作:

next(st for st in s.split('\n') \
if st.startswith("-- Status Change") and \
st.endswith('Complete'))\
.strip("-- Status Change:")[:10]

>>'19/09/2017'

您可以使用正则表达式来实现这一点,如下所示:

r'Status Change:(\d{2}\/\d{2}\/\d{4}).*?Complete'
下面是一个示例,以查看此正则表达式的实际应用


正如您提到的,您正在使用pandas,您可以利用该方法。

对于数据帧,您可以执行以下操作:

df['log'].str.extract('(?P<Date>[\d/]+).*Status = Complete')

线的长度是常数吗?完整的一行总是第二行吗?不幸的是,它有时在不同的行上,但行的长度似乎是一致的谢谢你@quang Hoang!你介意简要解释一下“?P[\d/]+.*Status=Complete”是如何工作的吗?你可以将该模式粘贴到regex101以了解更多细节。哦,很好,我不知道它的存在!谢谢
         Date
0         NaN
1  19/09/2017
2         NaN
3         NaN
4         NaN
5         NaN
6         NaN
7         NaN
8         NaN
input_dictionary = {
    'log': {
        0: '-- Status Change:01/09/2017 9:32:13 AM, C K:: Status = Ready to be fit',
        1: '-- Status Change:19/09/2017 7:53:28 AM, C K:: Status = Complete',
        2: '-- Status Change:29/08/2017 8:20:04 AM, C K:: Status = Ready to Schedule',
        3: '-- Assigned To Change:29/08/2017 8:19:53 AM, C K:: Assigned To Joe   Blow',
        4: '-- Status Change:29/08/2017 8:19:53 AM, C K:: Status = Scheduled',
        5: '-- Status Change:22/08/2017 8:33:38 AM, C K:: Status = Sent',
        6: '-- Assigned To Change:22/08/2017 8:32:46 AM, C K:: Assigned To John   Doe',
        7: '-- Status Change:17/08/2017 1:52:07 PM, C K:: Status = Ready to Pull Plastic',
        8: '-- Started by Joe   Blow at Winnipeg on 15/08/2017 11:20:56 AM:: Assigned To Joe   Blow'
    }
}


import re
import pandas as pd

# Regex to match your date format
date_regex = r"(\d{2}/\d{2}/\d{4} \d{1,2}:\d{2}:\d{2} [AP]M).*Complete"

df = pd.DataFrame(input_dictionary)

# for each element in "log" apply regex extraction and add to new field "date_complete"
df["date_completed"] = df["log"].str.extract(date_regex)