2017-05-31 13 views
3

私は大量のファイル(〜4GB相当)を扱っています。これらのファイルには、次の形式の1〜100個のエントリが含まれています):regexや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: 
*** 

は今、私は何とか質量分析のためのパンダにこれらをインポートしたいが、明らかに私はパンダが処理できる形式にこれを変換する必要があると思います。

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 

(フォーマットは完璧ではないですが、うまくいけば、あなたのアイデアを得る)

:だから私は、この(ユーザーがファイルのタイトルである)のようなものを探して.CSVに上記の変換スクリプトを書きたいです

私はいくつかのコードを定期的に12のセグメントで情報を基にして作業していますが、悲しいことに、いくつかのフィールドにいくつかのホワイトラインが含まれています。私は基本的に行うために探していますは、次のとおりです。

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

Oh my bad、ユーザーはテキストファイル名から抽出されます(すべてのテキストファイルはuserIDに基づいています)。 – user3394131

+0

"***"で分割して改行で分割してみてください。それらを1つの文字列に結合し、それをテキストファイルに出力するよりも。 – 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

あなたは、正規表現とdictの理解を組み合わせて使用​​することがあります。

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  


説明生み出す
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) 

  1. 除算辞書内のすべてのペアを入れて各ライン
  2. 内のキーと値のペアのための
  3. ルックが

我々は辞書の発電機を持つ終わる両側に***に囲まれたさまざまな部分に文字列、これをpandasに送ります。

ヒント:

コードは、大量のデータ、特にない4ギガバイトでテストされていません。さらに、表現が機能するには、新しいregexモジュールが必要です。

+0

私のノートパソコンのバッテリーが正常に動作していない、うまくいけば、週末にこれをテストすることができます!いずれにせよ答えてくれてありがとう! – user3394131

+0

新しいバッテリーを注文しなければならなかったので、私のラップトップはついに復活しました。しかし、次のエラーが発生しています: 'A:\ Programmas \ Anaconda \ lib \ sre_parse.py in _parse(source、state) 760 break 761フラグがない文字の場合: - > 762 raise source。エラー( "不明なフラグ"、len(char)) 763 verbose = state.flags&SRE_FLAG_VERBOSE 764 continue これを修正する方法がわかりません。 – user3394131

関連する問題