web-dev-qa-db-fra.com

pandas - convertit une chaîne en une liste de chaînes

J'ai ce fichier 'file.csv' à lire avec les pandas:

Title|Tags
T1|"[Tag1,Tag2]"
T1|"[Tag1,Tag2,Tag3]"
T2|"[Tag3,Tag1]"

en utilisant

df = pd.read_csv('file.csv', sep='|')

la sortie est:

  Title              Tags
0    T1       [Tag1,Tag2]
1    T1  [Tag1,Tag2,Tag3]
2    T2       [Tag3,Tag1]

Je sais que la colonne Tags est une chaîne complète, puisque:

In [64]: df['Tags'][0][0]
Out[64]: '['

J'ai besoin de le lire comme une liste de chaînes comme ["Tag1","Tag2"]. J'ai essayé la solution fournie dans this question mais pas de chance, car j'ai les caractères [ et ] qui gâchent les choses.

La sortie attendue devrait être:

In [64]: df['Tags'][0][0]
Out[64]: 'Tag1'
5
Fabio Lamanna

Vous pouvez scinder la chaîne manuellement:

>>> df['Tags'] = df.Tags.apply(lambda x: x[1:-1].split(','))
>>> df.Tags[0]
['Tag1', 'Tag2']
4
Mike Müller

Ou 

df.Tags=df.Tags.str[1:-1].str.split(',').tolist()
3
Wen-Ben

Vous pouvez convertir la chaîne en liste à l'aide de strip et split.

df_out = df.assign(Tags=df.Tags.str.strip('[]').str.split(','))

df_out.Tags[0][0]

Sortie:

'Tag1'
3
Scott Boston

Votre df['Tags'] semble être une liste de chaînes. Si vous imprimez cette liste, vous devriez obtenir ["[tag1,tag2]","[Tag1,Tag2,Tag3]","[Tag3,Tag1]"]. C'est pourquoi, lorsque vous appelez le premier élément du premier élément, vous obtenez le premier caractère unique de la chaîne, plutôt que ce que vous voulez.

Vous devez soit analyser cette chaîne par la suite. Effectuer quelque chose comme

df['Tags'][0] = df['Tags'][0].split(',')

Mais comme vous l'avez vu dans votre exemple cité, cela vous donnera une liste qui ressemble à 

in: df['Tags'][0][0] 
out: '[tag1'`

Ce dont vous avez besoin est un moyen d’analyser la chaîne en modifiant plusieurs caractères. Vous pouvez utiliser une expression regex simple pour le faire. Quelque chose comme:

 import re
 df['Tags'][0] = re.findall(r"[\w']+", df['Tags'][0])
 print(df['Tags'][0][0])

imprimera:

 'tag1'

En utilisant l’autre réponse impliquant des convertisseurs Pandas, vous pouvez écrire un convertisseur comme celui-ci:

 def clean(seq_string):
      return re.findall(r"[\w']+", seq_string)

Si vous ne connaissez pas les expressions rationnelles, elles peuvent être assez puissantes, mais aussi imprévisibles si vous n'êtes pas sûr du contenu de vos chaînes d'entrée. L'expression utilisée ici r"[\w']+" correspondra à tout caractère alphanumérique et caractère de mot commun, elle soulignera et traitera tout le reste comme un point permettant à re.findall de scinder la liste en.

1
Veggiet

Je pense que vous pourriez utiliser le module JSON.

import json
import pandas

df = pd.read_csv('file.csv', sep='|')
df['Tags'] = df['Tags'].apply(lambda x: json.loads(x))

Ainsi, cela chargera votre cadre de données comme auparavant, puis appliquera une fonction lambda à chacun des éléments de la colonne Tags. La fonction lambda appelle json.loads() qui convertit la représentation sous forme de chaîne de la liste en liste réelle.

0
RHSmith159