2017-12-30 33 views
-2

Ich verwende str.contains für die Textanalyse in Pandas. Wenn für den Satz "Mein letzter Datenjob ein Analyst" war, möchte ich eine Kombination der Wörter "Daten" & "Analyst", aber gleichzeitig möchte ich die Anzahl der Wörter zwischen den beiden für die Kombination verwendeten Wörtern angeben (hier sind es 2 Wörter zwischen "Data" und "Analyst" .Zum Moment verwende ich (DataFile.XXX.str.contains ('job') & DataFile.XXX.str.contains ('Analyst') um die Zählungen für " Job Analyst“. Wie kann ich die Anzahl der Worte zwischen den zwei Worten in der str.contains Syntax angeben. Vielen Dank im VorausPython Textverarbeitung (str.contains)

+1

Könnten Sie bitte ein Beispiel Ihres DataFrame freigeben. Pandas kann eine wirklich nützliche Bibliothek sein, aber es ist nicht für alles gedacht. Textanalyse ... vielleicht .. hängt davon ab .. höchstwahrscheinlich nicht. Und bitte, bevor Sie weitere Fragen stellen, nehmen Sie 30 Minuten, um dies zu lesen: [fragen]. –

+0

Willkommen bei SO. Leider ist dies kein Diskussionsforum oder Tutorial. Bitte nehmen Sie sich die Zeit, [ask] und die anderen Links auf dieser Seite zu lesen. – wwii

+0

Ich weiß, wie man diese Frage beantwortet. Aber ich werde nicht, weil Ihre Frage nicht den Standards dieser Seite entspricht. Bitte stelle eine [mcve] zur Verfügung und lies auch [ask] .. –

Antwort

0

Sie können nicht. Zumindest dest~~POS=HEADCOMP nicht in einer einfachen oder standardisierten Art und Weise.

Selbst die Grundlagen, wie Sie ein "Wort" definieren, sind Los komplexer als Sie sich wahrscheinlich vorstellen. Wortparsing und lexikalische Nähe (z. B. "sind zwei Wörter innerhalb des Abstands D zueinander in Satz s?") Ist der Bereich von natural language processing (NLP). NLP- und Proximity-Suchen gehören nicht zu den grundlegenden Pandas und auch nicht zu Pythons Standard-String-Verarbeitung. Sie könnten etwas wie NLTK, the Natural Language Toolkit importieren, um dieses Problem in einer allgemeinen Weise zu lösen, aber das ist eine ganze andere Geschichte.

Lassen Sie uns einen einfachen Ansatz betrachten. Zuerst benötigen Sie eine Möglichkeit, eine Zeichenfolge in Wörter zu analysieren. Im Folgenden ist rau von NLP-Standards, wird aber für einfachere Fälle arbeiten:

def parse_words(s): 
    """ 
    Simple parser to grab English words from string. 
    CAUTION: A simplistic solution to a hard problem. 
      Many possibly-important edge- and corner-cases 
      not handled. Just one example: Hyphenated words. 
    """ 
    return re.findall(r"\w+(?:'[st])?", s, re.I) 

ZB:

>>> parse_words("and don't think this day's last moment won't come ") 
['and', "don't", 'think', 'this', "day's", 'last', 'moment', "won't", 'come'] 

Dann brauchen Sie einen Weg, um alle Indizes in einer Liste zu finden, wo ein Zielwort gefunden:

def list_indices(target, seq): 
    """ 
    Return all indices in seq at which the target is found. 
    """ 
    indices = [] 
    cursor = 0 
    while True: 
     try: 
      index = seq.index(target, cursor) 
     except ValueError: 
      return indices 
     else: 
      indices.append(index) 
      cursor = index + 1 

Und schließlich ein Entscheidungs ​​Wrapper:

So
def words_within(target_words, s, max_distance, case_insensitive=True): 
    """ 
    Determine if the two target words are within max_distance positiones of one 
    another in the string s. 
    """ 
    if len(target_words) != 2: 
     raise ValueError('must provide 2 target words') 

    # fold case for case insensitivity 
    if case_insensitive: 
     s = s.casefold() 
     target_words = [tw.casefold() for tw in target_words] 
     # for Python 2, replace `casefold` with `lower` 

    # parse words and establish their logical positions in the string 
    words = parse_words(s) 
    target_indices = [list_indices(t, words) for t in target_words] 

    # words not present 
    if not target_indices[0] or not target_indices[1]: 
     return False 

    # compute all combinations of distance for the two words 
    # (there may be more than one occurance of a word in s) 
    actual_distances = [i2 - i1 for i2 in target_indices[1] for i1 in target_indices[0]] 

    # answer whether the minimum observed distance is <= our specified threshold 
    return min(actual_distances) <= max_distance 

dann:

>>> s = "and don't think this day's last moment won't come at last" 
>>> words_within(["THIS", 'last'], s, 2) 
True 

>>> words_within(["think", 'moment'], s, 2) 
False 

Das einzige, was ist noch zu tun Karte, die zurück zu Pandas:

df = pd.DataFrame({'desc': [ 
    'My latest Data job was an Analyst', 
    'some day my prince will come', 
    'Oh, somewhere over the rainbow bluebirds fly', 
    "Won't you share a common disaster?", 
    'job! rainbow! analyst.' 
]}) 

df['ja2'] = df.desc.apply(lambda x: words_within(["job", 'analyst'], x, 2)) 
df['ja3'] = df.desc.apply(lambda x: words_within(["job", 'analyst'], x, 3)) 

Dies ist im Grunde, wie Sie das Problem lösen würde . Denken Sie daran, es ist eine grobe und einfache Lösung. Einige einfach gestellte Fragen werden nicht einfach beantwortet. NLP-Fragen gehören oft dazu.

Verwandte Themen