1
votes

Diviser la chaîne de valeur de clé en python et la déplacer dans une colonne df

Voici la colonne que j'ai, je veux diviser en clé-valeur et stocker dans une nouvelle colonne dans pandas df.

{"FontStyle"=>"Gill Sans Standard", "FontSize"=>"Medium (3mm)"}
{"Font Style"=>"Gill Sans Standard","Font Size"=>"Medium (3mm)"}
{"Font Style":"Script","Font Size":"Medium (3mm)"}
{"Font Style"=>"Gill Sans Standard","Font Size"=>"Medium (3mm)"}
{"Font Style":"Gill Sans Standard","Font Size":"Medium (3mm)"}

Le principal problème est que certains d'entre eux ont '= > 'alors que certains ont deux points

Je veux deux nouvelles colonnes dans df, une pour le style de police et une autre pour la taille de la police et les valeurs respectées qu'elles contiennent

si quelqu'un peut m'aider à y parvenir, alors ce serait génial, et aussi si vous pouviez me recommander un livre / tutoriel pour regex qui serait super.

Merci


1 commentaires

Quel est votre résultat requis, pouvez-vous le mentionner également?


3 Réponses :


0
votes

Je pense que regex ici n'est pas nécessaire, utilisez:

d = {'=>':':', 'FontSize':'Font Size','FontStyle':'Font Style'}

regex = '|'.join(r"{}".format(x) for x in d.keys())
df1 = (df['col'].dropna()
                .str.replace(regex, lambda x: d[x.group()], regex=True)
                .apply(ast.literal_eval))
df2 = pd.DataFrame(df1.values.tolist())[['Font Size','Font Style']].dropna(how='all')
print (df2)
      Font Size          Font Style
0  Medium (3mm)  Gill Sans Standard
1  Medium (3mm)  Gill Sans Standard
2  Medium (3mm)              Script
3  Medium (3mm)  Gill Sans Standard
4  Medium (3mm)  Gill Sans Standard

import ast

print (df)
                                                 col
0  {"FontStyle"=>"Gill Sans Standard", "FontSize"...
1  {"Font Style"=>"Gill Sans Standard","Font Size...
2  {"Font Style":"Script","Font Size":"Medium (3m...
3  {"Font Style"=>"Gill Sans Standard","Font Size...
4  {"Font Style":"Gill Sans Standard","Font Size"...
5                                                NaN

Explication :

  1. Commencez par supprimer les lignes manquantes en DataFrame.dropna
  2. Utilisez ensuite Series.str.replace pour les valeurs du dictionnaire
  3. Convertir les valeurs en dictionnaires par ast.literal_eval
  4. Créer un nouveau DataFrame
  5. Si nécessaire, filtrer uniquement les colonnes par liste et déplacer uniquement les lignes de NaN


4 commentaires

Je reçois ce message d'erreur `nœud ou chaîne malformé: nan`


il y a 145 valeurs nulles dans cette colonne


la solution fonctionne bien, existe-t-il un moyen de fusionner ces colonnes en seulement 2? et oui, nous devons supprimer les valeurs nan


@Vijayaraghavan - Il suffit de voir qu'il y a un remplacement multiple nécessaire, donc la réponse a été modifiée.



1
votes

Ce n'est de loin pas le code le plus efficace mais cela ferait le travail.

      Font Size          Font Style
0  Medium (3mm)  Gill Sans Standard
1  Medium (3mm)  Gill Sans Standard
2  Medium (3mm)              Script
3  Medium (3mm)  Gill Sans Standard

Le résultat du code ci-dessus:

import pandas as pd
import ast

text = '''{"FontStyle"=>"Gill Sans Standard", "FontSize"=>"Medium (3mm)"}
{"Font Style"=>"Gill Sans Standard","Font Size"=>"Medium (3mm)"}
{"Font Style"=>"Script","Font Size"=>"Medium (3mm)"}
{"Font Style"=>"Gill Sans Standard","Font Size"=>"Medium (3mm)"}'''

my_list = []

text = text.replace("FontStyle", "Font Style")
text = text.replace("FontSize", "Font Size")
text = text.replace("=>", ":")
text = text.split("\n")

for one_dict in text:
    my_list.append(ast.literal_eval(one_dict))

df = pd.DataFrame(my_list)
print(df)

J'espère que cela aide. :-) Faites-moi savoir si c'est le cas.


0 commentaires

1
votes

Essayez ceci:

import ast
df['col'] = df['col'].str.replace('=>', ': ').str.replace('FontSize', 'Font Size').str.replace('FontStyle', 'Font Style')
df['col']= df["col"].apply(lambda x : dict(ast.literal_eval(x)))
df1 = df['col'].apply(pd.Series)


1 commentaires

Pouvez-vous me dire pourquoi ne pas utiliser eval?