2 votes

Pandas divise une colonne de dataframe

J'ai le cadre de données suivant où je veux diviser la Col2 en plusieurs colonnes :

DataFrame d'entrée :

>>> mydf= pd.DataFrame({'Col1':['AA','AB','AAC'], 'Col2':['AN||Ind(0.9)','LN||RED(8.9)','RN||RED(9.8)'], 'Col3':['log1','log2','log3']})

>>> mydf
   Col1      Col2      Col3
0   AA  AN||Ind(0.9)  log1
1   AB  LN||RED(8.9)  log2
2  AAC  RN||RED(9.8)  log3

DataFrame souhaité :

  Col1  Col2 Col3  Col4  Col5
0   AA   AN  log1  Ind   0.9
1   AB   LN  log2  RED   8.9
2  AAC   RN  log3  RED   9.8

J'ai commencé par l'application, mais la suite nécessitera quelques étapes. Un raccourci ?

mydf['Col4']=mydf['Col2'].apply(lambda x: str(x).split('||')[0])

Je ne comprends pas non plus pourquoi l'opération suivante génère une erreur de valeur :

mydf['Col2'].str.split('||', expand=True)

ValueError: split() requires a non-empty pattern match.

4voto

piRSquared Points 159

Vous pouvez diviser les colonnes avec str.extract y assign

regex = '(?P<Col2>.*)\|{2,}(?P<Col4>.*)\((?P<Col5>.*)\)'
mydf.assign(**mydf.Col2.str.extract(regex, expand=True).to_dict('list'))

  Col1 Col2  Col3 Col4 Col5
0   AA   AN  log1  Ind  0.9
1   AB   LN  log2  RED  8.9
2  AAC   RN  log3  RED  9.8

Ou de manière équivalente avec combine_first

regex = '(?P<Col2>.*)\|{2,}(?P<Col4>.*)\((?P<Col5>.*)\)'
mydf.Col2.str.extract(regex, expand=True).combine_first(mydf)

  Col1 Col2  Col3 Col4 Col5
0   AA   AN  log1  Ind  0.9
1   AB   LN  log2  RED  8.9
2  AAC   RN  log3  RED  9.8

explication

Cela utilise une expression régulière pour analyser le Col2 valeurs et affecter des noms de colonnes en même temps

regex = '(?P<Col2>.*)\|{2,}(?P<Col4>.*)\((?P<Col5>.*)\)'
  • '(?P<Col2>.*)\|{2,}' va tout saisir jusqu'au premier double | et l'appeler Col2
  • '(?P<Col4>.*)' récupère tout jusqu'aux parenthèses et l'appelle Col4
  • '\((?P<Col5>.*)\)' récupère tout ce qui se trouve entre les parenthèses et l'appelle Col5
  • enfin, nous réassignons soit Col2 en écrasant les données existantes Col2 ou nous utilisons combine_first où nous utilisons par défaut la nouvelle formule Col2 valeurs.

2voto

Vaishali Points 21664

La réponse de @piRSquared est étonnante, comme d'habitude, et elle a été approuvée. Je ne fais que publier mon approche. Je l'ai gardé très simple

mydf[['Col2', 'Col4', 'Col5']]= mydf.Col2.str.extract('(.*?)\|\|(.*?)\((.*?)\)', expand = True)

La colonne 2 est automatiquement réaffectée, il n'est donc pas nécessaire de supprimer une colonne par la suite.

    Col1    Col2    Col3    Col4    Col5
0   AA      AN      log1    Ind     0.9
1   AB      LN      log2    RED     8.9
2   AAC     RN      log3    RED     9.8

1voto

MaxU Points 5284

Utilisation de RegEx à partir de la solution du grand @piRSquared

In [59]: regex = '(?P<Col2>.*)\|{2,}(?P<Col4>.*)\((?P<Col5>.*)\)'

In [60]: mydf = mydf.join(mydf.pop('Col2').str.extract(regex, expand=True)) \
                    .sort_index(axis=1)

In [61]: mydf
Out[61]:
  Col1 Col2  Col3 Col4 Col5
0   AA   AN  log1  Ind  0.9
1   AB   LN  log2  RED  8.9
2  AAC   RN  log3  RED  9.8

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X