3
votes

Divisez les phrases des pandas en nombre de phrases et en mots

J'ai un dataframe pandas comme celui-ci:

Sentence#         Word        Tag
  1                I         Object 
  1               love       Object
  1               apple      fruit
  2                I         Object
  2               ate        Object
  2               potato     vegetable

J'ai essayé d'utiliser une boucle for Cela fonctionne lentement et je ne pense pas que ce soit ce que nous devrions faire avec les pandas.

Je veux créer une autre base de données pandas sur ceci comme:

Text            start    end    entity     value
I love apple      7       11    fruit      apple
I ate potato      6       11    vegetable  potato

Divisez la colonne de texte en mots et numéros de phrase. À part le mot d'entité, les autres mots seront marqués comme Object.


3 commentaires

Cela sera beaucoup plus difficile si «valeur» a des phrases ou des phrases (c'est-à-dire plus d'un mot).


@coldspeed Je rencontre ce problème maintenant que la «valeur» a des phrases et des phrases, connaissez-vous la solution de ce problème beaucoup plus difficile?


C'est une solution beaucoup plus complexe ... Je recommande d'ouvrir une nouvelle question. Si vous n'avez pas de réponse dans 2 jours, faites-le moi savoir et j'instaurerai une prime dessus.


3 Réponses :


2
votes

J'utilise annulation ici après str.split

df.Text=df.Text.str.split(' ')
yourdf=unnesting(df,['Text'])
yourdf.loc[yourdf.Text.values!=yourdf.value.values,'entity']='object'
yourdf
     Text  start  end     entity   value
0       I      7   11     object   apple
0    love      7   11     object   apple
0   apple      7   11      fruit   apple
1       I      6   11     object  potato
1     ate      6   11     object  potato
1  potato      6   11  vegetable  potato


1 commentaires

Wow, je n'ai jamais vu ce fil, génial. Ont préféré dans mes favoris;}



2
votes

Utilisation de la fonction expand J'ai publié dans cette discussion , vous pouvez

def expand(df, col, sep=','):
    r = df[col].str.split(sep)
    d = {c: df[c].values.repeat(r.str.len(), axis=0) for c in df.columns}
    d[col] = [i for sub in r for i in sub]
    return pd.DataFrame(d)

Puis simple

df['Tag'] = np.where(df.Text.ne(df.value), ['Object'], df.entity)


>>> df[['Text', 'Tag']]

    Text    Tag
0   I       Object
1   love    Object
2   apple   fruit
3   I       Object
4   ate     Object
5   potato  vegetable

df = expand(df, 'Text', sep=' ')


0 commentaires

5
votes

Utilisez split , stack et map:

u = df.Text.str.split(expand=True).stack()

pd.DataFrame({
    'Sentence': u.index.get_level_values(0) + 1, 
    'Word': u.values, 
    'Entity': u.map(dict(zip(df.value, df.entity))).fillna('Object').values
})

   Sentence    Word     Entity
0         1       I     Object
1         1    love     Object
2         1   apple      fruit
3         2       I     Object
4         2     ate     Object
5         2  potato  vegetable

Remarque: si vous exécutez la v0.24 ou version ultérieure, veuillez utiliser .to_numpy () au lieu de .values ​​ a >.


4 commentaires

J'adore cette réponse. Un morceau de code propre. Note de bas de page: pandas doc recommande .to_numpy () sur .values ​​


@Erfan Je sais; D La seule chose est, si OP est sur une version plus ancienne (très probablement), to_numpy lancera simplement une erreur d'attribut. Mais j'en ferai mention dans la réponse.


Je vois que ça a du sens. J'aurais dû être plus clair. Je voulais dire aussi une note d'accompagnement.


Btw merci d'avoir lié ce fil, une excellente information. Impossible de trouver cela dans la documentation. Je me demandais quelle était la raison de la dépréciation de .values ​​.