Vos données à votre portée avec Salesforce, Python, SQL, & et plus

Need event music? 🎸

Live and recorded jazz, pop, and meditative music for your virtual conference / Zoom wedding / yoga class / private party with quality sound and a smooth technical experience

Modification des données CSV / XLSX en Python pour admins Salesforce : vidéo et notes

09 Feb 2019 🔖 python pandas csv excel feuilles de calcul tutoriels salesforce samedi salesforce
💬 FR

Post Header Image

Table de matières

Revoir la démonstration du 09 fév sur la simplicité et la puissance du Python pour modifier les feuilles de calcul – déstinée surtout aux administrateurs Salesforce.

Introduction

J’ai fait une démonstration “pratique” (interactive) “Salesforce Saturday”, déstinée aux administrateurs Salesforce, durante une heure.

Nous les admins, nous faisons tous de travaux avec Data Loader (2).

  • On exporte des données aux fichiers CSV / XLSX.
  • On les transforme avec Microsoft Excel.
  • On importe le nouveau fichier à Salesforce avec Data Loader.

Mais quoi faire quand cette étape de transformation devient un peu pénible ?

Heureusement, en 2019, il existe un langage de programmation très bien aimé des non-développeurs, c’est à dire le Python.

J’ai démontré la facilité et la puissance de Python pour modifier les feuilles de calcul – surtout quand elles sont très grosses, quand l’on fait de tâches répétitives, et quand il faut rejoindre 2+ feuilles (sérieusement, qui rêve de faire un VLOOKUP) ?

Niveau tout débutant en programmation (mais avoir une certaine capacité avec les champs de formule et avec les formules en Excel vous aiderait – c’est au même niveau de difficulté).

Diapositives

Cliquez ici pour télécharger un fichier PDF des diapositives

Enregistrement en vidéo

(Cliquez ici pour voir l’enregistrement)

Exercises

Pourquoi coder nº 1 : modifier un gros fichier

Comme vous pouvez voir dans mon article de blog du 08 jan 2019, “Filtrer un gros fichier CSV avec Python”, Python peut modifier de très gros fichiers beaucoup plus vite que Excel.

On a supprimé les enregistrements dont le pays était l’Algérie, l’Arménie, l’Australie, ou la Barbade avec Excel et avec Python.

  • En Excel, cette opération a fallu 7 secondes pour un fichier de 100.000 enregistrements (et n’a pas terminé en quelques minutes avec 1.000.000 enregistrements 😱).
  • Avec Python, on a fini en 0,02 secondes pour les 100.000 et en 0,2 secondes pour les 1.000.000 enregistrements.

Le code entier est dans les diapositives; le code qui importe est :

import pandas
mauvaispays = ['Algeria','Armenia','Australia','Barbados']

df1 = pandas.read_csv('c:\\example\\100000 Sales Records.csv')
df1 = df1[~df1['Country'].isin(mauvaispays)]

df2 = pandas.read_csv('c:\\example\\1000000 Sales Records.csv')
df2 = df2[~df2['Country'].isin(mauvaispays)]

Notez: le “~” dans ce code indique “ne pas” et renverse l’effet de “.isin()

Voir aussi “affectation des variables” sur Numworks pour comprendre l’importance du symbole “=” et comment il fonctionne avec “df1” et “df2” dans ce code.

Je sais que le syntaxe est nouveau pour vous, et donc il y a une certaine difficulté à peu près pareille à la première fois que vous avez dû composer une formule compliquée en Excel (VLOOKUP, je te regarde !!), mais vous vous y habituerez. Et même sans connaître le syntaxe, il n’est pas mal de suivre, n’est-ce pas ?

Je vous conseille de copier-coller-modifier des exemples que vous trouverez en ligne, selon vos besoins, sans trop vous inquiéter de mémoriser le syntaxe. C’est ce que je fais, moi. 😊

Les données sont du blog “E for Excel“.

Pourquoi coder nº 2 : tâches répétitives

Je recommande toujours de continuer d’utiliser Excel à chaque opportunité. Mais une tâche facile de quelques minutes en Excel peut devenir pénible s’il faut le refaire tous les jours.

J’ai démontré une série d’étapes qui n’a fallu qu’une minute en Excel:

  • Ajouter une colonne “Notes”
  • Filtrer le fichier 3 fois
  • Ajouter 3 notes selon les données pendant les opérations de filtrer.

Normalement, une minute, ça va. Moi, je préférerais normalement Excel pour achever cette tâche !

Mais s’il fallait le faire chaque jour ? Même chaque semaine ? J’aurais envie d’automatiser mon travail … alors Python à l’aide !

Ici je commence avec le fichier “1000 Sales Records.csv(du blog “E for Excel“). Je ne le modifie pas directement, parce que j’ai peur de détruire mes données originales avec de mauvais code. Au lieu de cela, je crée un nouveau fichier1000-avec-notes.csv”.

import pandas

df = pandas.read_csv('c:\\example\\1000 Sales Records.csv')

lignes_cool_m = (df['Country'].str.startswith('M')) & (df['Order Priority'] == 'M')
lignes_froid = df['Country'].isin(['Canada','Greenland'])
lignes_gros_commandes = df['Total Revenue'] > 5000000

df['Notes'] = None
df['Notes'][lignes_cool_m] = 'Cool -- deux M !'
df['Notes'][lignes_froid] = 'Il fait froid'
df['Notes'][lignes_gros_commandes] = 'On commande beaucoup'

df.to_csv('c:\\example\\1000-avec-notes.csv', index=False)

Comme j’ai dit plus tôt, copiez-collez-modifiez. Jouez !

Je sais bien que tous les usages de “[” et de “]” peuvent confondre, mais … ils ne sont pas trop difficile à deviner avec l’expérimentation.

Faîtes attention à ne pas écraser votre fichier originel (créez toujours un nouveau fichier) et vous pourrez expérimenter à votre guise.

Pourquoi coder nº 3 : rejoindre des fichiers

La jointure des tableaux, c’est vraiment mon cas d’utilisation préféré pour le code Python.

  1. Me souvenir du syntaxe VLOOKUP() / INDEX(MATCH()) (RECHERCHEV() / INDEX(EQUIV()) en français ?) m’embête tellement.
  2. Créer de colonnes supplémentaires pour concaténer les colonnes composantes un critère de concordances entre feuilles … je déteste de faire le poirier comme ça !
  3. Copier-coller-modifier mes formules RECHERCHEV() de colonne en colonne pour ajouter chaque colonne de la deuxième feuille … beurk.
  4. Ne pas savoir, quand je regarde ma formule dans un an, de quelles données elle s’agit (c’est quoi dans la colonne “AJ” ?!) ? Non, merci !

Voici la folie de rejoindre des données en Excel : c’est la formule d’une seule cellule ci-dessous. UNE SEULE ! Et quelles sortes de données se trouvent dans 'Feuille2'!$A:$A et 'Feuille2'!$G:$G ? Aucune idée sans regarder.

=IF(
 ISNA(
  INDEX(
   'Feuille2'!$A:$A,
   MATCH(
    TRIM($F2),
    'Feuille2'!$G:$G,
	0
   )
  )
 ),
 "",
 INDEX(
  'Feuille2'!$A:$A,
  MATCH(
   TRIM($F2),
   'Feuille2'!$G:$G,
   0
  )
 )
)

Par contre, voici une jointure en Python, qui lit les feuilles “Feuille1” et “Feuille2” d’un fichier “C:\exemple\deuxfeuilles.xlsx” et écrit sur la disque dur trois nouveaux fichiers:

  1. unefeuille_comme_excel.xlsx
  2. unefeuille_tous_enregistrements.xlsx
  3. unefeuille_enregistrements_uniques.xlsx
import pandas

df1 = pandas.read_excel('c:\\example\\deuxfeuilles.xlsx', sheet_name='Feuille1')
df2 = pandas.read_excel('c:\\example\\deuxfeuilles.xlsx', sheet_name='Feuille2')

df2 = df2.rename(columns={'LastName':'Last', 'FirstName':'First', 'Em':'Email'})

jointuredf = df1.merge(df2, how='left', on=['Last','First','Email'])
jointure2df = df1.merge(df2, how='outer', on=['Last','First','Email'], indicator=True)
jointure3df = jointure2df.query('_merge != "both"')

jointuredf.to_excel('c:\\example\\unefeuille_comme_excel.xlsx', index=False)
jointure2df.to_excel('c:\\example\\unefeuille_tous_enregistrements.xlsx', index=False)
jointure3df.to_excel('c:\\example\\unefeuille_enregistrements_uniques.xlsx', index=False)

Moi je trouve le code Python tout à fait plus lisible, si je m’imagine un an plus tard, que je trouve le code de la formule Excel.

(Et notez que j’ai pas même encore copié-collé mon code aux autres cellules, donc écrire ce formule n’est pas tout mon travail en Excel.)

Si les contenus de la “Feuille1” sont ainsi :

Id First Last Email Company
5829 Jimmy Buffet [email protected] RCA
2894 Shirley Chisholm [email protected] United States Congress
294 Marilyn Monroe [email protected] Fox
30829 Cesar Chavez [email protected] United Farm Workers
827 Vandana Shiva [email protected] Navdanya
9284 Andrea Smith [email protected] University of California
724 Albert Howard [email protected] Imperial College of Science

Et si les contenus de la “Feuille2” sont ainsi :

PersonId FirstName LastName Em FavoriteFood
983mv Shirley Temple [email protected] Lollipops
9e84f Andrea Smith [email protected] Kale
k28fo Donald Duck [email protected] Pancakes
x934 Marilyn Monroe [email protected] Carrots
8xi Albert Howard [email protected] Potatoes
02e Vandana Shiva [email protected] Amaranth

Alors les contenus des 3 fichiers de sortie sont ainsi:

nº 1 : unefeuille_comme_excel.xlsx
Id First Last Email Company PersonId FavoriteFood
5829 Jimmy Buffet [email protected] RCA    
2894 Shirley Chisholm [email protected] United States Congress    
294 Marilyn Monroe [email protected] Fox x934 Carrots
30829 Cesar Chavez [email protected] United Farm Workers    
827 Vandana Shiva [email protected] Navdanya 02e Amaranth
9284 Andrea Smith [email protected] University of California 9e84f Kale
724 Albert Howard [email protected] Imperial College of Science    
nº 2 : unefeuille_tous_enregistrements.xlsx
Id First Last Email Company PersonId FavoriteFood _merge
5829 Jimmy Buffet [email protected] RCA     left_only
2894 Shirley Chisholm [email protected] United States Congress     left_only
294 Marilyn Monroe [email protected] Fox x934 Carrots both
30829 Cesar Chavez [email protected] United Farm Workers     left_only
827 Vandana Shiva [email protected] Navdanya 02e Amaranth both
9284 Andrea Smith [email protected] University of California 9e84f Kale both
724 Albert Howard [email protected] Imperial College of Science     left_only
  Shirley Temple [email protected]   983mv Lollipops right_only
  Donald Duck [email protected]   k28fo Pancakes right_only
  Albert Howard [email protected]   8xi Potatoes right_only
nº 3 : unefeuille_enregistrements_uniques.xlsx
Id First Last Email Company PersonId FavoriteFood _merge
5829 Jimmy Buffet [email protected] RCA     left_only
2894 Shirley Chisholm [email protected] United States Congress     left_only
30829 Cesar Chavez [email protected] United Farm Workers     left_only
724 Albert Howard [email protected] Imperial College of Science     left_only
  Shirley Temple [email protected]   983mv Lollipops right_only
  Donald Duck [email protected]   k28fo Pancakes right_only
  Albert Howard [email protected]   8xi Potatoes right_only

Exercises Collaboratives

Code de base

Pour les exercises collaboratives, on a commencé avec ce code-ci, que vous pouvez modifier ici:

import pandas
pandas.set_option('expand_frame_repr', False)

chemin1 = 'https://raw.githubusercontent.com/pypancsv/pypancsv/master/docs/_data/sample1.csv'
chemin2 = 'https://raw.githubusercontent.com/pypancsv/pypancsv/master/docs/_data/sample2.csv'

def p(quelquechose):
  print(quelquechose)
  print('---CLOISON---')

# #########################
# Ne supprimez pas le code au-dessus.  Le professeur l'a fourni.
# #########################


Code final

Après avoir fini, on a composé ce code-ci (ce qui inclue beaucoup de code transformé en “commentaires” pour qu’il n’éxécute pas), modifiable ici:

import pandas
pandas.set_option('expand_frame_repr', False)

chemin1 = 'https://raw.githubusercontent.com/pypancsv/pypancsv/master/docs/_data/sample1.csv'
chemin2 = 'https://raw.githubusercontent.com/pypancsv/pypancsv/master/docs/_data/sample2.csv'

def p(quelquechose):
  print(quelquechose)
  print('---CLOISON---')

# #########################
# Ne supprimez pas le code au-dessus.  Le professeur l'a fourni.
# #########################

#p('Salut !')

df1 = pandas.read_csv(chemin1)
#p(df1)

#p(len(df1))
#p(df1.columns)
#p(len(df1.columns))
#p(list(df1.columns))
#p(sorted(df1.columns))

col_nom = df1['Last']
#p(col_nom)
#p(list(col_nom))
cn_unq = col_nom.unique()
#p(cn_unq)
#p(len(cn_unq))

interessants = ['First','Last']
cols_nom_prenom = df1[interessants]
#p(cols_nom_prenom)
col_prenom = df1['First']
tous_nom = pandas.concat([col_nom, col_prenom])
#p(sorted(tous_nom))

df2 = pandas.read_csv(chemin2)
df2match = df2.rename(columns={'FirstName':'First', 'LastName':'Last'})
mergedf = df1.merge(df2match, on=interessants, how='outer', indicator=True)
#p(mergedf)
#p(mergedf.query('_merge != "both"'))

mergedf.to_csv('resultat.csv', index=False)
p('Fin')

Exercise 1 – afficher “Salut !” sur l’écran

Ce code :

p('Salut !')

A produit cette sortie :

Salut !
---CLOISON---

Exercise 2 – lire un fichier CSV et l’afficher sur l’écran

Ce code :

df1 = pandas.read_csv(chemin1)
p(df1)

A produit cette sortie :

      Id    First      Last           Email                      Company
0   5829    Jimmy    Buffet  [email protected]                          RCA
1   2894  Shirley  Chisholm  [email protected]       United States Congress
2    294  Marilyn    Monroe  [email protected]                          Fox
3  30829    Cesar    Chavez  [email protected]          United Farm Workers
4    827  Vandana     Shiva  [email protected]                     Navdanya
5   9284   Andrea     Smith  [email protected]     University of California
6    724   Albert    Howard  [email protected]  Imperial College of Science
---CLOISON---

Exercise 3 – afficher le nombre d’enregistrements dans le CSV et quelques infos sur les noms de ses colonnes

Ce code :

p(len(df1))
p(df1.columns)
p(len(df1.columns))
p(list(df1.columns))
p(sorted(df1.columns))

A produit cette sortie :

7
---CLOISON---
Index(['Id', 'First', 'Last', 'Email', 'Company'], dtype='object')
---CLOISON---
5
---CLOISON---
['Id', 'First', 'Last', 'Email', 'Company']
---CLOISON---
['Company', 'Email', 'First', 'Id', 'Last']
---CLOISON---

Exercise 4 – afficher quelques infos sur la colonne “nom de famille”

Ce code :

col_nom = df1['Last']
p(col_nom)
p(list(col_nom))
cn_unq = col_nom.unique()
p(cn_unq)
p(len(cn_unq))

A produit cette sortie :

0      Buffet
1    Chisholm
2      Monroe
3      Chavez
4       Shiva
5       Smith
6      Howard
Name: Last, dtype: object
---CLOISON---
['Buffet', 'Chisholm', 'Monroe', 'Chavez', 'Shiva', 'Smith', 'Howard']
---CLOISON---
['Buffet' 'Chisholm' 'Monroe' 'Chavez' 'Shiva' 'Smith' 'Howard']
---CLOISON---
7
---CLOISON---

Exercise 5 – afficher que les colonnes composant les noms + concaténer toutes les parties des noms dans une seule liste en ordre alphabétique

Ce code :

interessants = ['First','Last']
cols_nom_prenom = df1[interessants]
p(cols_nom_prenom)
col_prenom = df1['First']
tous_nom = pandas.concat([col_nom, col_prenom])
p(sorted(tous_nom))

A produit cette sortie :

     First      Last
0    Jimmy    Buffet
1  Shirley  Chisholm
2  Marilyn    Monroe
3    Cesar    Chavez
4  Vandana     Shiva
5   Andrea     Smith
6   Albert    Howard
---CLOISON---
['Albert', 'Andrea', 'Buffet', 'Cesar', 'Chavez', 'Chisholm', 'Howard', 'Jimmy', 'Marilyn', 'Monroe', 'Shirley', 'Shiva', 'Smith', 'Vandana']
---CLOISON---

Exercise 6 – rejoindre deux feuilles de calcul

Ce code:

df2 = pandas.read_csv(chemin2)
df2match = df2.rename(columns={'FirstName':'First', 'LastName':'Last'})
mergedf = df1.merge(df2match, on=interessants, how='outer', indicator=True)
p(mergedf)
p(mergedf.query('_merge != "both"'))

A produit cette sortie :

        Id    First      Last           Email                      Company PersonId                     Em FavoriteFood      _merge
0   5829.0    Jimmy    Buffet  [email protected]                          RCA      NaN                    NaN          NaN   left_only
1   2894.0  Shirley  Chisholm  [email protected]       United States Congress      NaN                    NaN          NaN   left_only
2    294.0  Marilyn    Monroe  [email protected]                          Fox     x934         [email protected]      Carrots        both
3  30829.0    Cesar    Chavez  [email protected]          United Farm Workers      NaN                    NaN          NaN   left_only
4    827.0  Vandana     Shiva  [email protected]                     Navdanya      02e         [email protected]     Amaranth        both
5   9284.0   Andrea     Smith  [email protected]     University of California    9e84f         [email protected]         Kale        both
6    724.0   Albert    Howard  [email protected]  Imperial College of Science      8xi  [email protected]     Potatoes        both
7      NaN  Shirley    Temple             NaN                          NaN    983mv         [email protected]    Lollipops  right_only
8      NaN   Donald      Duck             NaN                          NaN    k28fo         [email protected]     Pancakes  right_only
---CLOISON---
        Id    First      Last           Email                 Company PersonId              Em FavoriteFood      _merge
0   5829.0    Jimmy    Buffet  [email protected]                     RCA      NaN             NaN          NaN   left_only
1   2894.0  Shirley  Chisholm  [email protected]  United States Congress      NaN             NaN          NaN   left_only
3  30829.0    Cesar    Chavez  [email protected]     United Farm Workers      NaN             NaN          NaN   left_only
7      NaN  Shirley    Temple             NaN                     NaN    983mv  [email protected]ample.com    Lollipops  right_only
8      NaN   Donald      Duck             NaN                     NaN    k28fo  [email protected]     Pancakes  right_only
---CLOISON---

Exercise 7 – créer un nouveau fichier CSV des données modifiées

Ce code:

mergedf.to_csv('resultat.csv', index=False)

A produit un fichier “resultat.csv” dont les contenus sont :

Id,First,Last,Email,Company,PersonId,Em,FavoriteFood,_merge
5829.0,Jimmy,Buffet,[email protected],RCA,,,,left_only
2894.0,Shirley,Chisholm,[email protected],United States Congress,,,,left_only
294.0,Marilyn,Monroe,[email protected],Fox,x934,[email protected],Carrots,both
30829.0,Cesar,Chavez,[email protected],United Farm Workers,,,,left_only
827.0,Vandana,Shiva,[email protected],Navdanya,02e,[email protected],Amaranth,both
9284.0,Andrea,Smith,[email protected],University of California,9e84f,[email protected],Kale,both
724.0,Albert,Howard,[email protected],Imperial College of Science,8xi,[email protected],Potatoes,both
,Shirley,Temple,,,983mv,[email protected],Lollipops,right_only
,Donald,Duck,,,k28fo,[email protected],Pancakes,right_only

Ou, plus lisible :

Id First Last Email Company PersonId Em FavoriteFood _merge
5829.0 Jimmy Buffet [email protected] RCA       left_only
2894.0 Shirley Chisholm [email protected] United States Congress       left_only
294.0 Marilyn Monroe [email protected] Fox x934 [email protected] Carrots both
30829.0 Cesar Chavez [email protected] United Farm Workers       left_only
827.0 Vandana Shiva [email protected] Navdanya 02e [email protected] Amaranth both
9284.0 Andrea Smith [email protected] University of California 9e84f [email protected] Kale both
724.0 Albert Howard [email protected] Imperial College of Science 8xi [email protected] Potatoes both
  Shirley Temple     983mv [email protected] Lollipops right_only
  Donald Duck     k28fo [email protected] Pancakes right_only

Attention ! Avez-vous remarqué que dans les deux fois que je vous ai montré cette jointure de feuilles, les infos d’Albert Howard se diffèrent un peu ?

  • Plus tôt, j’ai correspondu les 2 feuilles aux colonnes “prénom”, “nom de famille”, et “adresse mail”.
  • Cette fois-ci, j’ai correspondu les 2 feuilles aux colonnes “prénom” et “nom de famille”.

Albert a des adresses mail différentes entre les deux feuilles, alors les résultats de la jointure sont différentes.

Comme en Excel, comme en Salesforce, attention à vos données !

Solution “Coding On Demand”

Un des étudiants a demandé de l’aide avec un problème avancé. Voici une transformation que j’espère approcherait ses besoins :

Données d’entrée :

Id First Last Email Company
5829 Jimmy Buffet [email protected] RCA
2894 Shirley Chisholm [email protected] United States Congress
294 Marilyn Monroe [email protected] Fox
30829 Cesar Chavez [email protected] United Farm Workers
827 Vandana Shiva [email protected] Navdanya
9284 Andrea Smith [email protected] University of California
724 Albert Howard [email protected] Imperial College of Science

Code Python :

import pandas
chemin1 = 
df1 = pandas.read_csv('https://raw.githubusercontent.com/pypancsv/pypancsv/master/docs/_data/sample1.csv')

df1['parties'] = df1['Email'].str.split(pat='@', n=1, expand=False)

mauvais_lignes = df1['parties'].apply(lambda x : len(x) > 0 and x[0] in ['cc','mm'])

df1['nouveau'] = None
df1.loc[mauvais_lignes, 'nouveau'] = df1['parties'].apply(lambda x: x[1].split('.')[0])
df1.loc[mauvais_lignes, 'Company'] = df1['parties'].apply(lambda x: x[1].split('.')[1])
df1.loc[mauvais_lignes, 'Email'] = df1['parties'].apply(lambda x: '@' + x[1])

df1 = df1.drop(columns=['parties'])

df1.to_csv('c:\\example\\fichierdesortie.csv', index=False)

Données de sortie :

Id First Last Email Company nouveau
5829 Jimmy Buffet [email protected] RCA  
2894 Shirley Chisholm [email protected] United States Congress  
294 Marilyn Monroe @example.com com example
30829 Cesar Chavez @example.com com example
827 Vandana Shiva [email protected] Navdanya  
9284 Andrea Smith [email protected] University of California  
724 Albert Howard [email protected] Imperial College of Science  

Ressources et liens

Anglais

Français

Désolée – beaucoup des ressources en français sont déstinées aux Data Scientists, alors trop compliquées pour les débutants qui ne veulent que faire quelques petites transformations à leurs feuilles de calcul.

Le Python pour la modification des fichiers CSV / XLS peut être très simple à écrire pour les tout débutants, mais en ce moment, il n’y a pas de telle documentation en français.

J’espère changer tout ça en éditant des ressources !

Mais pour le moment, voici les ressources les plus proches que j’ai pu trouver en français …

--- ---