2017-05-31 160 views
3

我正在处理大量文件(值大约4GB),它们都包含1到100个条目之间的任何地方,格式如下(两个***之间是一个条目):通过正则表达式和/或Python从文本文件中提取信息

*** 
Type:status 
Origin: @z_rose yes 
Text: yes 
URL: 
ID: 95482459084427264 
Time: Mon Jul 25 08:16:06 CDT 2011 
RetCount: 0 
Favorite: false 
MentionedEntities: 20776334 
Hashtags: 
*** 
*** 
Type:status 
Origin: @aaronesilvers text 
Text: text 
URL: 
ID: 95481610861953024 
Time: Mon Jul 25 08:12:44 CDT 2011 
RetCount: 0 
Favorite: false 
MentionedEntities: 2226621 
Hashtags: 
*** 
*** 
Type:status 
Origin: @z_rose text 
Text: text and stuff 
URL: 
ID: 95480980026040320 
Time: Mon Jul 25 08:10:14 CDT 2011 
RetCount: 0 
Favorite: false 
MentionedEntities: 20776334 
Hashtags: 
*** 

现在我想以某种方式将这些项目导入大熊猫进行质量分析,但很明显,我不得不将其转换成格式大熊猫可以处理。所以我想写的是,上述转换到.csv看起来像这样(用户是文件标题)的脚本:

User Type Origin    Text URL ID    Time       RetCount Favorite MentionedEntities Hashtags 
4012987 status @z_rose yes   yes Null 95482459084427264 Mon Jul 25 08:16:06 CDT 2011 0   false 20776334   Null 
4012987 status @aaronsilvers text text Null 95481610861953024 Mon Jul 25 08:12:44 CDT 2011 0   false 2226621   Null 

(格式是不完美的,但希望你的想法)

我已经有一些代码工作的基础上,它经常在12的信息段,但不幸的是,一些文件包含一些领域的几个whitelines。什么我基本上希望做的是:

fields[] =['User', 'Type', 'Origin', 'Text', 'URL', 'ID', 'Time', 'RetCount', 'Favorite', 'MentionedEntities', 'Hashtags'] 
starPair = 0; 
User = filename; 
read(file) 
#Determine if the current entry has ended 
if(stringRead=="***"){ 
    if(starPair == 0) 
     starPair++; 
    if(starPair == 1){ 
     row=row++; 
     starPair = 0; 
    } 
} 
#if string read matches column field 
if(stringRead == fields[]) 
    while(strRead != fields[]) #until next field has been found 
     #extract all characters into correct column field 

然而,问题出现某些字段可以包含的字段的字[] ..我可以检查一个\ n字符第一,这将大大减少量的错误条目,但不会消除它们。

任何人都可以指向正确的方向吗?

在此先感谢!

+0

用户来自哪里? – depperm

+0

哦,我的坏,用户从文本文件名称中提取(所有文本文件都是由用户ID)。 – user3394131

+0

也许只是尝试按“***”拆分,然后用换行符拆分结果?将它们连接到一个字符串并将其打印到文本文件中。 – Eswemenasja

回答

1

你的代码/伪代码看起来不像python,但是因为你有python标签,所以我会这样做。首先,将文件读入一个字符串,然后遍历每个字段并制作一个正则表达式来查找后面的值,将结果推送到2d列表中,然后将该2d列表输出为CSV。此外,您的CSV看起来更像是一个TSV(制表符分隔,而不是逗号分隔)。

import re 
import csv 

filename='4012987' 
User=filename 

# read your file into a string 
with open(filename, 'r') as myfile: 
    data=myfile.read() 

fields =['Type', 'Origin', 'Text', 'URL', 'ID', 'Time', 'RetCount', 'Favorite', 'MentionedEntities', 'Hashtags'] 
csvTemplate = [['User','Type', 'Origin', 'Text', 'URL', 'ID', 'Time', 'RetCount', 'Favorite', 'MentionedEntities', 'Hashtags']] 

# for each field use regex to get the entry 
for n,field in enumerate(fields): 
    matches = re.findall(field+':\s?([^\n]*)\n+', data) 
    # this should run only the first time to fill your 2d list with the right amount of lists 
    while len(csvTemplate)<=len(matches): 
    csvTemplate.append([None]*(len(fields)+1)) # Null isn't a python reserved word 
    for e,m in enumerate(matches): 
    if m != '': 
     csvTemplate[e+1][n+1]=m.strip() 
# set the User column 
for i in range(1,len(csvTemplate)): 
    csvTemplate[i][0] = User 
# output to csv....if you want tsv look at https://stackoverflow.com/a/29896136/3462319 
with open("output.csv", "wb") as f: 
    writer = csv.writer(f) 
    writer.writerows(csvTemplate) 
+0

我的笔记本电脑电池工作不正常,希望在周末能够测试这个!无论如何谢谢你的答案! – user3394131

+0

嗨,我的笔记本电脑现在已经修复,对于延迟应答表示歉意。我不得不将“wb”改成“w”,因为它不会运行。谢谢! – user3394131

+0

只是想跟进,它似乎是完美的工作。最后我实际上拥有将近20GB的数据,而且我测试过的所有样本都非常完美。非常感谢! – user3394131

2

您可以使用正则表达式和一个字典理解的组合:

import regex as re, pandas as pd 

rx_parts = re.compile(r'^{}$(?s:.*?)^{}$'.format(re.escape('***'), re.escape('***')), re.MULTILINE) 
rx_entry = re.compile(r'^(?P<key>\w+):[ ]*(?P<value>.+)$', re.MULTILINE) 

result = ({m.group('key'): m.group('value') 
      for m in rx_entry.finditer(part.group(0))} 
      for part in rx_parts.finditer(your_string_here)) 

df = pd.DataFrame(result) 
print(df) 

其中产量

Favorite Hashtags     ID MentionedEntities    Origin \ 
0 false   95482459084427264   20776334   @z_rose yes 
1 false   95481610861953024   2226621 @aaronesilvers text 
2 false   95480980026040320   20776334   @z_rose text 

    RetCount   Text       Time Type URL 
0  0    yes Mon Jul 25 08:16:06 CDT 2011 status  
1  0   text Mon Jul 25 08:12:44 CDT 2011 status  
2  0 text and stuff Mon Jul 25 08:10:14 CDT 2011 status  


说明:

  1. 鸿沟字符串转换成不同的部分,由***两侧
  2. 查找每行
  3. 键值对把所有对在一个字典

我们最终不得不字典的发电机包围然后我们将其输入pandas

提示:

的代码没有被大量数据的测试,尤其是不4GB。此外,您需要使用较新的regex模块才能使表达式正常工作。

+0

我的笔记本电脑电池无法正常工作,我希望能够在周末期间对此进行测试!无论如何谢谢你的答案! – user3394131

+0

不得不订购新电池,我的笔记本电脑终于再次工作,对延迟应答表示歉意。虽然我发现了以下错误: 'A:\ Programmas \蟒蛇\在_parse LIB \ sre_parse.py(源,州) 760破 761如果字符不在标志: - > 762升源。错误(“未知标志”,len(char)) 763 verbose = state.flags&SRE_FLAG_VERBOSE 764 continue ' 我似乎无法弄清楚如何解决它。 – user3394131

相关问题