2016-11-22 2 views
-1

Ich habe eine riesige Textdatei, bestehend aus etwa 18.000 Textproben, getrennt durch eine konsequente Anzahl von Vorwärts-Slates: ////////////// //////effektive Methode für Text Mining in VBA/Excel

Example: 

//////////////////// 
P11/000568 

name: john 
age: 18 
hobbies: cycling, drawing 

//////////////////// 
P12/000894 
name: eva 
age: 19 
hobbies: football, soccer, baseball 

ich für das Wort „Fußball“ auf „mine“ diese Textdatei wollen, so dass jedes Mal das Programm dieses Wort „sieht“, wird eine neue Zeile in Excel erstellt wird, enthält der Name des Themas und der Code über

 A   B   age 
1 P12/000894  eva   19 

ich habe einige Codes (vba- excel, in jedem Stück Text in ein Array zu lesen) versucht, aber da die txt-Datei ist so groß, mein PC schmilzt beim Ausführen des Codes. Irgendwelche Ideen auf, die beste Methode (vba-excel bevorzugt, Power/powerquery ??)

Dank C

+3

Bitte senden Sie den Code Sie haben --- post it auf dieser Seite (oben), wenn der Code Fehler oder ein Problem hat. Poste es auf [Codereview] (http://codereview.stackexchange.com/), wenn dein Code fehlerfrei funktioniert, du aber Leistungsverbesserungen und Kommentare anforderst. – PeterT

Antwort

0

Edit: ein video ist jetzt verfügbar Erläuterung 2 Ansätze. Der schnelle Ansatz ist in dem Code unten.

In Excel/Power-Abfrage kann es mit dem folgenden Code erfolgen:

let 
    Source = Excel.CurrentWorkbook(){[Name="Input"]}[Content], 
    Typed = Table.TransformColumnTypes(Source,{{"Text", type text}}), 
    RemovedBlankRows = Table.SelectRows(Typed, each not List.IsEmpty(List.RemoveMatchingItems(Record.FieldValues(_), {"", null}))), 
    Combined = Table.FromColumns({List.Skip(RemovedBlankRows[Text],4),List.Skip(RemovedBlankRows[Text],1),List.Skip(RemovedBlankRows[Text],2),List.Skip(RemovedBlankRows[Text],3)},{"Original","Code","Name","Age"}), 
    Filtered = Table.SelectRows(Combined, each Text.Contains([Original], "soccer")), 
    Removed = Table.RemoveColumns(Filtered,{"Original"}), 
    Transformed = Table.TransformColumns(Removed, {{"Name", each Text.RemoveRange(_, 0, 6), type text},{"Age", each Int64.From(Text.RemoveRange(_, 0, 5)), Int64.Type}}) 
in 
    Transformed 
+0

Hallo. Ihr Code hat einen schwerwiegenden Nachteil: Sie nehmen an, dass es eine feste Anzahl von Parametern pro Datensatz gibt und diese in einer festen Reihenfolge stehen. – Eugene

+1

@Eugene: gut beobachtet! Eine Voraussetzung dafür, dass mein Code funktioniert, ist, dass die Anzahl und Reihenfolge der Parameter festgelegt werden muss. Das ist eine Einschränkung, und wenn die Voraussetzung nicht erfüllt wird, ist das auch ein Nachteil, noch schlimmer: in diesem Fall kann mein Code nicht verwendet werden. – MarcelBeug

+0

Marcel, auf der anderen Seite scheint es schneller zu arbeiten als meine auf großen (2M Zeilen) Datensätzen, da Table.Distinct und Table.Pivot sehr ressourcenintensiv sind. – Eugene

0

Hier ist, was Sie in PowerQuery wollen:

let 
    //Delimiter is REQUIRED, Default of "," messes the table! 
    Source = Csv.Document(File.Contents("C:\Users\Eugene\Desktop\test.txt"),[Delimiter="`", Columns=1, Encoding=1251, QuoteStyle=QuoteStyle.None]), 
    Split = Table.SplitColumn(Source,"Column1",Splitter.SplitTextByEachDelimiter({":"}, QuoteStyle.Csv, false),{"Parameter", "Value"}), 
    FilteredExcessiveRows = Table.SelectRows(Split, each ([Parameter] <> "" and [Parameter] <> "////////////////////")), 
    AddCode = Table.AddColumn(FilteredExcessiveRows, "Code", each if _[Value] = null then _[Parameter] else null), 
    FillDown = Table.FillDown(AddCode,{"Code"}), 
    RemoveDuplicates = Table.Distinct(FillDown, {"Code", "Parameter"}), 
    Filtered2 = Table.SelectRows(RemoveDuplicates, each ([Value] <> null)), 
    Pivot = Table.Pivot(Filtered2, List.Distinct(Filtered2[Parameter]), "Parameter", "Value"), 
    Filtered3 = Table.SelectRows(Pivot, each Text.Contains([hobbies], "soccer")), 
    RemoveHobbies = Table.RemoveColumns(Filtered3,{"hobbies"}) 
in 
    RemoveHobbies 
Verwandte Themen