[Pandas] J'ai essayé d'analyser les données de ventes avec Python [Pour les débutants]

J'ai regardé une vidéo de conférence Python par Keith Galli, un youtubeur étranger, et j'ai essayé le travail.

Résolvons de vrais problèmes de science des données en utilisant la bibliothèque Pandas de Python! ] Solving real world data science tasks with Python Pandas! Le niveau de difficulté n'est pas élevé et c'est un anglais simple, alors jetez un œil.

Il s'agit d'une vidéo d'une heure et demie environ. C'est une explication très polie. Chez stackoverflow (site de questions-réponses sur la programmation de la version étrangère) sur Google Il montre également le processus de recherche d'une solution.

C'est une tâche à analyser à l'aide de données CSV Excel. Les données peuvent être téléchargées depuis son Github.

Cliquez ici pour Github

Je cours sur un notebook jupyter.

Je le fais en ajoutant des suppléments au code en japonais.

Si vous regardez la vidéo et que vous la touchez, je pense que c'est la meilleure façon de pratiquer les pandas.

Vous pouvez avoir une idée de l'atmosphère en lisant simplement cet article.

Créer un bloc de données à partir de la lecture de données

Chargez la bibliothèque pandas, os

import pandas as pd
import os

Tout d'abord, vérifiez quel type de données est inclus (obtenez la liste des noms de fichiers)

files = [file for file in os.listdir("Sales_Data")]
for file in files:
    print(file)
Sales_April_2019.csv
Sales_August_2019.csv
Sales_December_2019.csv
Sales_February_2019.csv
Sales_January_2019.csv
Sales_July_2019.csv
Sales_June_2019.csv
Sales_March_2019.csv
Sales_May_2019.csv
Sales_November_2019.csv
Sales_October_2019.csv
Sales_September_2019.csv

Il semble que les données du nom du fichier à janvier-décembre 2019 soient incluses, je souhaite combiner les données pour analyse

Tout d'abord, créez un bloc de données vide pour stocker toutes les données

all_months_data = pd.DataFrame()

Afin de combiner toutes les données du mois, nous placerons le fichier csv de chaque mois dans le bloc de données vide l'un après l'autre.

for file in files:
    df = pd.read_csv("Sales_Data/" + file)
    all_months_data = pd.concat([all_months_data,df])

Eh bien, les 5 premières lignes de données ressemblent à ceci

all_months_data.head()
Order ID Product Quantity Ordered Price Each Order Date Purchase Address
0 176558 USB-C Charging Cable 2 11.95 04/19/19 08:46 917 1st St, Dallas, TX 75001
1 NaN NaN NaN NaN NaN NaN
2 176559 Bose SoundSport Headphones 1 99.99 04/07/19 22:30 682 Chestnut St, Boston, MA 02215
3 176560 Google Phone 1 600 04/12/19 14:38 669 Spruce St, Los Angeles, CA 90001
4 176560 Wired Headphones 1 11.99 04/12/19 14:38 669 Spruce St, Los Angeles, CA 90001

Sortie des données combinées (À ce stade, puisque le numéro de série n'est pas requis, ajoutez index = False à l'argument)

all_months_data.to_csv("all_data.csv",index=False)

Après avoir confirmé les données de sortie, essayez à nouveau de lire les données combinées.

all_data = pd.read_csv("all_data.csv")
all_data.head()
Order ID Product Quantity Ordered Price Each Order Date Purchase Address
0 176558 USB-C Charging Cable 2 11.95 04/19/19 08:46 917 1st St, Dallas, TX 75001
1 NaN NaN NaN NaN NaN NaN
2 176559 Bose SoundSport Headphones 1 99.99 04/07/19 22:30 682 Chestnut St, Boston, MA 02215
3 176560 Google Phone 1 600 04/12/19 14:38 669 Spruce St, Los Angeles, CA 90001
4 176560 Wired Headphones 1 11.99 04/12/19 14:38 669 Spruce St, Los Angeles, CA 90001

Travail 1: Quand a été le mois avec les ventes les plus élevées et combien avez-vous gagné?

En regardant la colonne, il y a une colonne Date de commande = date de commande, mais il n'y a pas de données uniquement pour le mois, alors créons-en une nouvelle

Les deux premiers caractères de la colonne de date de commande sont probablement les données du mois

all_data['Month'] = all_data['Order Date'].str[0:2]

Puisqu'il a été converti en chaîne de caractères, retournons-le à nouveau à la valeur numérique

all_data['Month'] = all_data['Month'].astype('int32')
all_data.head()
---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

<ipython-input-77-ffc394ccb2ad> in <module>
----> 1 all_data['Month'] = all_data['Month'].astype('int32')
      2 all_data.head()


/opt/anaconda3/lib/python3.7/site-packages/pandas/core/generic.py in astype(self, dtype, copy, errors, **kwargs)
   5880             # else, only a single dtype is given
   5881             new_data = self._data.astype(
-> 5882                 dtype=dtype, copy=copy, errors=errors, **kwargs
   5883             )
   5884             return self._constructor(new_data).__finalize__(self)


/opt/anaconda3/lib/python3.7/site-packages/pandas/core/internals/managers.py in astype(self, dtype, **kwargs)
    579 
    580     def astype(self, dtype, **kwargs):
--> 581         return self.apply("astype", dtype=dtype, **kwargs)
    582 
    583     def convert(self, **kwargs):


/opt/anaconda3/lib/python3.7/site-packages/pandas/core/internals/managers.py in apply(self, f, axes, filter, do_integrity_check, consolidate, **kwargs)
    436                     kwargs[k] = obj.reindex(b_items, axis=axis, copy=align_copy)
    437 
--> 438             applied = getattr(b, f)(**kwargs)
    439             result_blocks = _extend_blocks(applied, result_blocks)
    440 


/opt/anaconda3/lib/python3.7/site-packages/pandas/core/internals/blocks.py in astype(self, dtype, copy, errors, values, **kwargs)
    557 
    558     def astype(self, dtype, copy=False, errors="raise", values=None, **kwargs):
--> 559         return self._astype(dtype, copy=copy, errors=errors, values=values, **kwargs)
    560 
    561     def _astype(self, dtype, copy=False, errors="raise", values=None, **kwargs):


/opt/anaconda3/lib/python3.7/site-packages/pandas/core/internals/blocks.py in _astype(self, dtype, copy, errors, values, **kwargs)
    641                     # _astype_nansafe works fine with 1-d only
    642                     vals1d = values.ravel()
--> 643                     values = astype_nansafe(vals1d, dtype, copy=True, **kwargs)
    644 
    645                 # TODO(extension)


/opt/anaconda3/lib/python3.7/site-packages/pandas/core/dtypes/cast.py in astype_nansafe(arr, dtype, copy, skipna)
    705         # work around NumPy brokenness, #1987
    706         if np.issubdtype(dtype.type, np.integer):
--> 707             return lib.astype_intsafe(arr.ravel(), dtype).reshape(arr.shape)
    708 
    709         # if we have a datetime/timedelta array of objects


pandas/_libs/lib.pyx in pandas._libs.lib.astype_intsafe()


ValueError: cannot convert float NaN to integer

J'ai une erreur

Quand je lis la déclaration d'erreur, il dit que NaN ne peut pas être quantifié.

La combinaison de is_na et de toutes les fonctions renverra True s'il y a au moins un NaN.

axis = 1 est une fonction qui retourne le traitement ligne par ligne

Demandez-leur de renvoyer toutes les lignes contenant NaN

nan_df = all_data[all_data.isna().any(axis=1)]
nan_df
Order ID Product Quantity Ordered Price Each Order Date Purchase Address Month
1 NaN NaN NaN NaN NaN NaN NaN
356 NaN NaN NaN NaN NaN NaN NaN
735 NaN NaN NaN NaN NaN NaN NaN
1433 NaN NaN NaN NaN NaN NaN NaN
1553 NaN NaN NaN NaN NaN NaN NaN
... ... ... ... ... ... ... ...
185176 NaN NaN NaN NaN NaN NaN NaN
185438 NaN NaN NaN NaN NaN NaN NaN
186042 NaN NaN NaN NaN NaN NaN NaN
186548 NaN NaN NaN NaN NaN NaN NaN
186826 NaN NaN NaN NaN NaN NaN NaN

545 rows × 7 columns

Il y avait aussi 545 lignes

Effacer les données contenant NaN

all_data = all_data.dropna(how='all')
all_data.head()
Order ID Product Quantity Ordered Price Each Order Date Purchase Address Month
0 176558 USB-C Charging Cable 2 11.95 04/19/19 08:46 917 1st St, Dallas, TX 75001 04
2 176559 Bose SoundSport Headphones 1 99.99 04/07/19 22:30 682 Chestnut St, Boston, MA 02215 04
3 176560 Google Phone 1 600 04/12/19 14:38 669 Spruce St, Los Angeles, CA 90001 04
4 176560 Wired Headphones 1 11.99 04/12/19 14:38 669 Spruce St, Los Angeles, CA 90001 04
5 176561 Wired Headphones 1 11.99 04/30/19 09:27 333 8th St, Los Angeles, CA 90001 04

Très bien, revenons au mois précédent et réessayons

all_data['Month'] = all_data['Month'].astype('int32')
all_data.head()
---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

<ipython-input-80-ffc394ccb2ad> in <module>
----> 1 all_data['Month'] = all_data['Month'].astype('int32')
      2 all_data.head()


/opt/anaconda3/lib/python3.7/site-packages/pandas/core/generic.py in astype(self, dtype, copy, errors, **kwargs)
   5880             # else, only a single dtype is given
   5881             new_data = self._data.astype(
-> 5882                 dtype=dtype, copy=copy, errors=errors, **kwargs
   5883             )
   5884             return self._constructor(new_data).__finalize__(self)


/opt/anaconda3/lib/python3.7/site-packages/pandas/core/internals/managers.py in astype(self, dtype, **kwargs)
    579 
    580     def astype(self, dtype, **kwargs):
--> 581         return self.apply("astype", dtype=dtype, **kwargs)
    582 
    583     def convert(self, **kwargs):


/opt/anaconda3/lib/python3.7/site-packages/pandas/core/internals/managers.py in apply(self, f, axes, filter, do_integrity_check, consolidate, **kwargs)
    436                     kwargs[k] = obj.reindex(b_items, axis=axis, copy=align_copy)
    437 
--> 438             applied = getattr(b, f)(**kwargs)
    439             result_blocks = _extend_blocks(applied, result_blocks)
    440 


/opt/anaconda3/lib/python3.7/site-packages/pandas/core/internals/blocks.py in astype(self, dtype, copy, errors, values, **kwargs)
    557 
    558     def astype(self, dtype, copy=False, errors="raise", values=None, **kwargs):
--> 559         return self._astype(dtype, copy=copy, errors=errors, values=values, **kwargs)
    560 
    561     def _astype(self, dtype, copy=False, errors="raise", values=None, **kwargs):


/opt/anaconda3/lib/python3.7/site-packages/pandas/core/internals/blocks.py in _astype(self, dtype, copy, errors, values, **kwargs)
    641                     # _astype_nansafe works fine with 1-d only
    642                     vals1d = values.ravel()
--> 643                     values = astype_nansafe(vals1d, dtype, copy=True, **kwargs)
    644 
    645                 # TODO(extension)


/opt/anaconda3/lib/python3.7/site-packages/pandas/core/dtypes/cast.py in astype_nansafe(arr, dtype, copy, skipna)
    705         # work around NumPy brokenness, #1987
    706         if np.issubdtype(dtype.type, np.integer):
--> 707             return lib.astype_intsafe(arr.ravel(), dtype).reshape(arr.shape)
    708 
    709         # if we have a datetime/timedelta array of objects


pandas/_libs/lib.pyx in pandas._libs.lib.astype_intsafe()


ValueError: invalid literal for int() with base 10: 'Or'

Ensuite, je reçois à nouveau une nouvelle erreur

Il semble que le mot «Ou» était inclus

Regardons la ligne qui contient "Ou"

temp_df = all_data[all_data['Order Date'].str[0:2] == "Or"]
temp_df.head()
Order ID Product Quantity Ordered Price Each Order Date Purchase Address Month
519 Order ID Product Quantity Ordered Price Each Order Date Purchase Address Or
1149 Order ID Product Quantity Ordered Price Each Order Date Purchase Address Or
1155 Order ID Product Quantity Ordered Price Each Order Date Purchase Address Or
2878 Order ID Product Quantity Ordered Price Each Order Date Purchase Address Or
2893 Order ID Product Quantity Ordered Price Each Order Date Purchase Address Or

Il semble que l'identité de "Ou" était "Date de commande".

Rafraîchissons les données en extrayant les données autres que les données contenant le mot "Date de commande"

all_data = all_data[all_data['Order Date'].str[0:2] != "Or"]
all_data.head()
Order ID Product Quantity Ordered Price Each Order Date Purchase Address Month
0 176558 USB-C Charging Cable 2 11.95 04/19/19 08:46 917 1st St, Dallas, TX 75001 04
2 176559 Bose SoundSport Headphones 1 99.99 04/07/19 22:30 682 Chestnut St, Boston, MA 02215 04
3 176560 Google Phone 1 600 04/12/19 14:38 669 Spruce St, Los Angeles, CA 90001 04
4 176560 Wired Headphones 1 11.99 04/12/19 14:38 669 Spruce St, Los Angeles, CA 90001 04
5 176561 Wired Headphones 1 11.99 04/30/19 09:27 333 8th St, Los Angeles, CA 90001 04

Soyons honnêtes pour la troisième fois et effectuons une quantification

all_data['Month'] = all_data['Order Date'].str[0:2]
all_data['Month'] = all_data['Month'].astype('int32')
all_data.head()
Order ID Product Quantity Ordered Price Each Order Date Purchase Address Month
0 176558 USB-C Charging Cable 2 11.95 04/19/19 08:46 917 1st St, Dallas, TX 75001 4
2 176559 Bose SoundSport Headphones 1 99.99 04/07/19 22:30 682 Chestnut St, Boston, MA 02215 4
3 176560 Google Phone 1 600 04/12/19 14:38 669 Spruce St, Los Angeles, CA 90001 4
4 176560 Wired Headphones 1 11.99 04/12/19 14:38 669 Spruce St, Los Angeles, CA 90001 4
5 176561 Wired Headphones 1 11.99 04/30/19 09:27 333 8th St, Los Angeles, CA 90001 4

J? ai compris

Ensuite, bien qu'il y ait Quantité commandée et Prix chacun, il n'y a pas de ventes essentielles.

Puisque PQ (ventes) = P (prix) x Q (quantité), ajoutez une colonne qui correspond à PQ.

all_data['Sales'] = all_data['Quantity Ordered'] * all_data['Price Each'] 
---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

/opt/anaconda3/lib/python3.7/site-packages/pandas/core/ops/__init__.py in na_op(x, y)
    967         try:
--> 968             result = expressions.evaluate(op, str_rep, x, y, **eval_kwargs)
    969         except TypeError:


/opt/anaconda3/lib/python3.7/site-packages/pandas/core/computation/expressions.py in evaluate(op, op_str, a, b, use_numexpr, **eval_kwargs)
    220     if use_numexpr:
--> 221         return _evaluate(op, op_str, a, b, **eval_kwargs)
    222     return _evaluate_standard(op, op_str, a, b)


/opt/anaconda3/lib/python3.7/site-packages/pandas/core/computation/expressions.py in _evaluate_numexpr(op, op_str, a, b, truediv, reversed, **eval_kwargs)
    126     if result is None:
--> 127         result = _evaluate_standard(op, op_str, a, b)
    128 


/opt/anaconda3/lib/python3.7/site-packages/pandas/core/computation/expressions.py in _evaluate_standard(op, op_str, a, b, **eval_kwargs)
     69     with np.errstate(all="ignore"):
---> 70         return op(a, b)
     71 


TypeError: can't multiply sequence by non-int of type 'str'


During handling of the above exception, another exception occurred:


TypeError                                 Traceback (most recent call last)

<ipython-input-84-7c1e2b69cbe2> in <module>
----> 1 all_data['Sales'] = all_data['Quantity Ordered'] * all_data['Price Each']


/opt/anaconda3/lib/python3.7/site-packages/pandas/core/ops/__init__.py in wrapper(left, right)
   1046 
   1047         with np.errstate(all="ignore"):
-> 1048             result = na_op(lvalues, rvalues)
   1049         return construct_result(
   1050             left, result, index=left.index, name=res_name, dtype=None


/opt/anaconda3/lib/python3.7/site-packages/pandas/core/ops/__init__.py in na_op(x, y)
    968             result = expressions.evaluate(op, str_rep, x, y, **eval_kwargs)
    969         except TypeError:
--> 970             result = masked_arith_op(x, y, op)
    971 
    972         return missing.dispatch_fill_zeros(op, x, y, result)


/opt/anaconda3/lib/python3.7/site-packages/pandas/core/ops/__init__.py in masked_arith_op(x, y, op)
    445         if mask.any():
    446             with np.errstate(all="ignore"):
--> 447                 result[mask] = op(xrav[mask], com.values_from_object(yrav[mask]))
    448 
    449     else:


TypeError: can't multiply sequence by non-int of type 'str'

Encore une fois, il contenait une chaîne

Je veux le réécrire sous une forme qui peut être calculée pour le moment, donc j'utiliserai la fonction "to_numeric"

all_data['Quantity Ordered'] = pd.to_numeric(all_data['Quantity Ordered'])
all_data['Price Each'] = pd.to_numeric(all_data['Price Each'])

Je vais essayer à nouveau

all_data['Sales'] = all_data['Quantity Ordered'] * all_data['Price Each'] 
all_data.head()
Order ID Product Quantity Ordered Price Each Order Date Purchase Address Month Sales
0 176558 USB-C Charging Cable 2 11.95 04/19/19 08:46 917 1st St, Dallas, TX 75001 4 23.90
2 176559 Bose SoundSport Headphones 1 99.99 04/07/19 22:30 682 Chestnut St, Boston, MA 02215 4 99.99
3 176560 Google Phone 1 600.00 04/12/19 14:38 669 Spruce St, Los Angeles, CA 90001 4 600.00
4 176560 Wired Headphones 1 11.99 04/12/19 14:38 669 Spruce St, Los Angeles, CA 90001 4 11.99
5 176561 Wired Headphones 1 11.99 04/30/19 09:27 333 8th St, Los Angeles, CA 90001 4 11.99

C'est sorti. Il semble que la réponse à la question sortira enfin

Pour le moment, je republierai la question.

Travail 1: Quand a été le mois avec les ventes les plus élevées et combien avez-vous gagné?

all_data.groupby('Month').sum()
Quantity Ordered Price Each Sales
Month
1 10903 1.811768e+06 1.822257e+06
2 13449 2.188885e+06 2.202022e+06
3 17005 2.791208e+06 2.807100e+06
4 20558 3.367671e+06 3.390670e+06
5 18667 3.135125e+06 3.152607e+06
6 15253 2.562026e+06 2.577802e+06
7 16072 2.632540e+06 2.647776e+06
8 13448 2.230345e+06 2.244468e+06
9 13109 2.084992e+06 2.097560e+06
10 22703 3.715555e+06 3.736727e+06
11 19798 3.180601e+06 3.199603e+06
12 28114 4.588415e+06 4.613443e+06

Je ne connais pas Pat, alors montrons-le

Installez la bibliothèque pour illustration

import matplotlib.pyplot as plt

Graphique tout en décidant de la plage de l'axe X

months = range(1,13)
results = all_data.groupby('Month').sum()
plt.bar(months,results['Sales'])
plt.xticks(months)
plt.xlabel('Month')
plt.ylabel('Sales')
plt.show()

output_60_0.png

C'était le travail 1.

Travail 2: Quelle ville a enregistré les ventes les plus élevées

Maintenant que nous avons une ligne de vente, le travail semble facile, mais faisons-le

Avant cela, revoyons à quoi ressemblaient les données.

all_data.head()
Order ID Product Quantity Ordered Price Each Order Date Purchase Address Month Sales
0 176558 USB-C Charging Cable 2 11.95 04/19/19 08:46 917 1st St, Dallas, TX 75001 4 23.90
2 176559 Bose SoundSport Headphones 1 99.99 04/07/19 22:30 682 Chestnut St, Boston, MA 02215 4 99.99
3 176560 Google Phone 1 600.00 04/12/19 14:38 669 Spruce St, Los Angeles, CA 90001 4 600.00
4 176560 Wired Headphones 1 11.99 04/12/19 14:38 669 Spruce St, Los Angeles, CA 90001 4 11.99
5 176561 Wired Headphones 1 11.99 04/30/19 09:27 333 8th St, Los Angeles, CA 90001 4 11.99

C'est comme extraire une partie des données dans la partie Adresse d'achat et la totaliser.

Créons une colonne City comme nous l'avons fait dans Sales

Je dois extraire une partie d'Adresse, mais quand je regarde les données d'Adress, je veux extraire uniquement le deuxième nom de ville comme "adresse, nom de ville, code postal".

Utilisez la fonction Apply pour fractionner par "," dans la fonction de fractionnement et appliquez-la à toutes les colonnes de la même colonne

all_data['City'] = all_data['Purchase Address'].apply(lambda x: x.split(',')[1])
all_data.head()
Order ID Product Quantity Ordered Price Each Order Date Purchase Address Month Sales City
0 176558 USB-C Charging Cable 2 11.95 04/19/19 08:46 917 1st St, Dallas, TX 75001 4 23.90 Dallas
2 176559 Bose SoundSport Headphones 1 99.99 04/07/19 22:30 682 Chestnut St, Boston, MA 02215 4 99.99 Boston
3 176560 Google Phone 1 600.00 04/12/19 14:38 669 Spruce St, Los Angeles, CA 90001 4 600.00 Los Angeles
4 176560 Wired Headphones 1 11.99 04/12/19 14:38 669 Spruce St, Los Angeles, CA 90001 4 11.99 Los Angeles
5 176561 Wired Headphones 1 11.99 04/30/19 09:27 333 8th St, Los Angeles, CA 90001 4 11.99 Los Angeles

Seule la ville a été divisée avec succès!

À propos, il y a un problème qui doit être pris en compte ici lors du total de City.

C'est le cas où City a le même nom mais d'autres pays ont le même nom. Si cela n'est pas pris en compte, ils seront additionnés et des résultats d'agrégation involontaires seront obtenus. (Exemple: Portlands dans l'Oregon et le Maine)

Cependant, il n'est pas nécessaire de créer une nouvelle colonne pour le nom du pays. Il vous suffit de mettre l'état (2 caractères) dans la cellule de la colonne Ville car il s'agrège uniquement. Cette fois, ce sera sous la forme de Ville (État). ex: Dallas (TX)

Plus tôt, je l'ai écrit en une seule ligne avec la fonction lambda, mais comme c'est un gros problème, créons une fonction pour obtenir respectivement le nom de la ville et le nom du pays. Il est également gentil avec le lecteur.

def get_city(address):
    return address.split(',')[1]

def get_state(address):
    return address.split(',')[2].split(' ')[1]
#Les données d'adresse d'achat sont des virgules(,)Vide après(" ")Parce qu'il y a, couper avec fente pour qu'il ne devienne pas artificiel une fois uni

all_data['City'] = all_data['Purchase Address'].apply(lambda x: f"{get_city(x)} ({get_state(x)})")
all_data.drop("State",axis=1)
Order ID Product Quantity Ordered Price Each Order Date Purchase Address Month Sales City
0 176558 USB-C Charging Cable 2 11.95 04/19/19 08:46 917 1st St, Dallas, TX 75001 4 23.90 Dallas (TX)
2 176559 Bose SoundSport Headphones 1 99.99 04/07/19 22:30 682 Chestnut St, Boston, MA 02215 4 99.99 Boston (MA)
3 176560 Google Phone 1 600.00 04/12/19 14:38 669 Spruce St, Los Angeles, CA 90001 4 600.00 Los Angeles (CA)
4 176560 Wired Headphones 1 11.99 04/12/19 14:38 669 Spruce St, Los Angeles, CA 90001 4 11.99 Los Angeles (CA)
5 176561 Wired Headphones 1 11.99 04/30/19 09:27 333 8th St, Los Angeles, CA 90001 4 11.99 Los Angeles (CA)
... ... ... ... ... ... ... ... ... ...
186845 259353 AAA Batteries (4-pack) 3 2.99 09/17/19 20:56 840 Highland St, Los Angeles, CA 90001 9 8.97 Los Angeles (CA)
186846 259354 iPhone 1 700.00 09/01/19 16:00 216 Dogwood St, San Francisco, CA 94016 9 700.00 San Francisco (CA)
186847 259355 iPhone 1 700.00 09/23/19 07:39 220 12th St, San Francisco, CA 94016 9 700.00 San Francisco (CA)
186848 259356 34in Ultrawide Monitor 1 379.99 09/19/19 17:30 511 Forest St, San Francisco, CA 94016 9 379.99 San Francisco (CA)
186849 259357 USB-C Charging Cable 1 11.95 09/30/19 00:18 250 Meadow St, San Francisco, CA 94016 9 11.95 San Francisco (CA)

185950 rows × 9 columns

C'est bon, tout ce que vous avez à faire est de faire la somme normalement

all_data.groupby('City').sum()
Quantity Ordered Price Each Month Sales
City
Atlanta (GA) 16602 2.779908e+06 104794 2.795499e+06
Austin (TX) 11153 1.809874e+06 69829 1.819582e+06
Boston (MA) 22528 3.637410e+06 141112 3.661642e+06
Dallas (TX) 16730 2.752628e+06 104620 2.767975e+06
Los Angeles (CA) 33289 5.421435e+06 208325 5.452571e+06
New York City (NY) 27932 4.635371e+06 175741 4.664317e+06
Portland (ME) 2750 4.471893e+05 17144 4.497583e+05
Portland (OR) 11303 1.860558e+06 70621 1.870732e+06
San Francisco (CA) 50239 8.211462e+06 315520 8.262204e+06
Seattle (WA) 16553 2.733296e+06 104941 2.747755e+06

San Francisco est le numéro un. En outre, vous pouvez voir que Portland est également correctement divisée.

Organisez le code utilisé le mois précédent

results = all_data.groupby('City').sum()
cities = [city for city, df in all_data.groupby('City')]
#Ville pour les étiquettes de l'axe des x: les nombres et les étiquettes seront disjoints à moins qu'ils ne soient dans le même ordre que lorsqu'ils sont rainurés ci-dessus.
plt.bar(cities,results['Sales'])
plt.xticks(cities,rotation="vertical")
#Si les villes sont affichées telles quelles, elles seront encombrantes, alors affichez-les verticalement.
plt.ylabel('Sales')
plt.xlabel('City name')
plt.show()

output_1.png

C'est fait!

Travail 3: Quand et quand une annonce doit-elle être placée (affichée) pour maximiser la probabilité qu'un client achète l'article?

Le travail est devenu comme la science des données à la fois (cependant, la conclusion n'est pas si logique d'abord)

Maintenant, comme d'habitude, revenons sur les données

all_data.head()
Order ID Product Quantity Ordered Price Each Order Date Purchase Address Month Sales City State
0 176558 USB-C Charging Cable 2 11.95 04/19/19 08:46 917 1st St, Dallas, TX 75001 4 23.90 Dallas (TX) TX 75001
2 176559 Bose SoundSport Headphones 1 99.99 04/07/19 22:30 682 Chestnut St, Boston, MA 02215 4 99.99 Boston (MA) MA 02215
3 176560 Google Phone 1 600.00 04/12/19 14:38 669 Spruce St, Los Angeles, CA 90001 4 600.00 Los Angeles (CA) CA 90001
4 176560 Wired Headphones 1 11.99 04/12/19 14:38 669 Spruce St, Los Angeles, CA 90001 4 11.99 Los Angeles (CA) CA 90001
5 176561 Wired Headphones 1 11.99 04/30/19 09:27 333 8th St, Los Angeles, CA 90001 4 11.99 Los Angeles (CA) CA 90001

Il serait peut-être intéressant d'examiner la relation entre la colonne Données de la commande et la colonne Ventes.

Modifions le type de données afin que la date de commande puisse être facilement traitée comme des données de date.

all_data['Order Date'] = pd.to_datetime(all_data['Order Date'])
all_data.head()
Order ID Product Quantity Ordered Price Each Order Date Purchase Address Month Sales City State
0 176558 USB-C Charging Cable 2 11.95 2019-04-19 08:46:00 917 1st St, Dallas, TX 75001 4 23.90 Dallas (TX) TX 75001
2 176559 Bose SoundSport Headphones 1 99.99 2019-04-07 22:30:00 682 Chestnut St, Boston, MA 02215 4 99.99 Boston (MA) MA 02215
3 176560 Google Phone 1 600.00 2019-04-12 14:38:00 669 Spruce St, Los Angeles, CA 90001 4 600.00 Los Angeles (CA) CA 90001
4 176560 Wired Headphones 1 11.99 2019-04-12 14:38:00 669 Spruce St, Los Angeles, CA 90001 4 11.99 Los Angeles (CA) CA 90001
5 176561 Wired Headphones 1 11.99 2019-04-30 09:27:00 333 8th St, Los Angeles, CA 90001 4 11.99 Los Angeles (CA) CA 90001

Le format des données a changé

Faisons une ligne d'heure, minute

Quand j'ai créé une colonne dans Month ou Sales, c'était une chaîne de caractères, j'ai donc utilisé Split etc., mais grâce à la modification du type de données plus tôt

all_data['Hour'] = all_data['Order Date'].dt.hour
all_data['Minute'] = all_data['Order Date'].dt.minute
all_data.head()
Order ID Product Quantity Ordered Price Each Order Date Purchase Address Month Sales City State Hour Minute
0 176558 USB-C Charging Cable 2 11.95 2019-04-19 08:46:00 917 1st St, Dallas, TX 75001 4 23.90 Dallas (TX) TX 75001 8 46
2 176559 Bose SoundSport Headphones 1 99.99 2019-04-07 22:30:00 682 Chestnut St, Boston, MA 02215 4 99.99 Boston (MA) MA 02215 22 30
3 176560 Google Phone 1 600.00 2019-04-12 14:38:00 669 Spruce St, Los Angeles, CA 90001 4 600.00 Los Angeles (CA) CA 90001 14 38
4 176560 Wired Headphones 1 11.99 2019-04-12 14:38:00 669 Spruce St, Los Angeles, CA 90001 4 11.99 Los Angeles (CA) CA 90001 14 38
5 176561 Wired Headphones 1 11.99 2019-04-30 09:27:00 333 8th St, Los Angeles, CA 90001 4 11.99 Los Angeles (CA) CA 90001 9 27

Visualisons une fois pour saisir les données

hours = [hour for hour, df in all_data.groupby('Hour')]
plt.plot(hours,all_data.groupby(['Hour']).count())
#Nombre de commandes par heure avec le temps sur l'axe X(Nombre de lignes)Agrégat
plt.xticks(hours)
plt.grid()
#Je veux voir une tendance claire pour chaque heure autant que possible, donc je vais ajouter une grille
plt.xlabel('Hour')
plt.ylabel('Orders')
plt.show()

output_2.png

Le pic est vers AM: 11 et PM: 7. Par conséquent, il semble bon d'afficher des publicités pendant cette période où le nombre de commandes (clients) est le plus élevé.

Travail 4: Quels produits sont les plus achetés ensemble en tant qu'ensemble?

all_data.head()
Order ID Product Quantity Ordered Price Each Order Date Purchase Address Month Sales City State Hour Minute
0 176558 USB-C Charging Cable 2 11.95 2019-04-19 08:46:00 917 1st St, Dallas, TX 75001 4 23.90 Dallas (TX) TX 75001 8 46
2 176559 Bose SoundSport Headphones 1 99.99 2019-04-07 22:30:00 682 Chestnut St, Boston, MA 02215 4 99.99 Boston (MA) MA 02215 22 30
3 176560 Google Phone 1 600.00 2019-04-12 14:38:00 669 Spruce St, Los Angeles, CA 90001 4 600.00 Los Angeles (CA) CA 90001 14 38
4 176560 Wired Headphones 1 11.99 2019-04-12 14:38:00 669 Spruce St, Los Angeles, CA 90001 4 11.99 Los Angeles (CA) CA 90001 14 38
5 176561 Wired Headphones 1 11.99 2019-04-30 09:27:00 333 8th St, Los Angeles, CA 90001 4 11.99 Los Angeles (CA) CA 90001 9 27

Il semble que vous puissiez comprendre si vous groupez par le même ID de commande

Vous pouvez facilement trier les valeurs que vous portez en utilisant la fonction dupliquée.

df = all_data[all_data['Order ID'].duplicated(keep=False)]
df.head(20)
Order ID Product Quantity Ordered Price Each Order Date Purchase Address Month Sales City State Hour Minute
3 176560 Google Phone 1 600.00 2019-04-12 14:38:00 669 Spruce St, Los Angeles, CA 90001 4 600.00 Los Angeles (CA) CA 90001 14 38
4 176560 Wired Headphones 1 11.99 2019-04-12 14:38:00 669 Spruce St, Los Angeles, CA 90001 4 11.99 Los Angeles (CA) CA 90001 14 38
18 176574 Google Phone 1 600.00 2019-04-03 19:42:00 20 Hill St, Los Angeles, CA 90001 4 600.00 Los Angeles (CA) CA 90001 19 42
19 176574 USB-C Charging Cable 1 11.95 2019-04-03 19:42:00 20 Hill St, Los Angeles, CA 90001 4 11.95 Los Angeles (CA) CA 90001 19 42
30 176585 Bose SoundSport Headphones 1 99.99 2019-04-07 11:31:00 823 Highland St, Boston, MA 02215 4 99.99 Boston (MA) MA 02215 11 31
31 176585 Bose SoundSport Headphones 1 99.99 2019-04-07 11:31:00 823 Highland St, Boston, MA 02215 4 99.99 Boston (MA) MA 02215 11 31
32 176586 AAA Batteries (4-pack) 2 2.99 2019-04-10 17:00:00 365 Center St, San Francisco, CA 94016 4 5.98 San Francisco (CA) CA 94016 17 0
33 176586 Google Phone 1 600.00 2019-04-10 17:00:00 365 Center St, San Francisco, CA 94016 4 600.00 San Francisco (CA) CA 94016 17 0
119 176672 Lightning Charging Cable 1 14.95 2019-04-12 11:07:00 778 Maple St, New York City, NY 10001 4 14.95 New York City (NY) NY 10001 11 7
120 176672 USB-C Charging Cable 1 11.95 2019-04-12 11:07:00 778 Maple St, New York City, NY 10001 4 11.95 New York City (NY) NY 10001 11 7
129 176681 Apple Airpods Headphones 1 150.00 2019-04-20 10:39:00 331 Cherry St, Seattle, WA 98101 4 150.00 Seattle (WA) WA 98101 10 39
130 176681 ThinkPad Laptop 1 999.99 2019-04-20 10:39:00 331 Cherry St, Seattle, WA 98101 4 999.99 Seattle (WA) WA 98101 10 39
138 176689 Bose SoundSport Headphones 1 99.99 2019-04-24 17:15:00 659 Lincoln St, New York City, NY 10001 4 99.99 New York City (NY) NY 10001 17 15
139 176689 AAA Batteries (4-pack) 2 2.99 2019-04-24 17:15:00 659 Lincoln St, New York City, NY 10001 4 5.98 New York City (NY) NY 10001 17 15
189 176739 34in Ultrawide Monitor 1 379.99 2019-04-05 17:38:00 730 6th St, Austin, TX 73301 4 379.99 Austin (TX) TX 73301 17 38
190 176739 Google Phone 1 600.00 2019-04-05 17:38:00 730 6th St, Austin, TX 73301 4 600.00 Austin (TX) TX 73301 17 38
225 176774 Lightning Charging Cable 1 14.95 2019-04-25 15:06:00 372 Church St, Los Angeles, CA 90001 4 14.95 Los Angeles (CA) CA 90001 15 6
226 176774 USB-C Charging Cable 1 11.95 2019-04-25 15:06:00 372 Church St, Los Angeles, CA 90001 4 11.95 Los Angeles (CA) CA 90001 15 6
233 176781 iPhone 1 700.00 2019-04-03 07:37:00 976 Hickory St, Dallas, TX 75001 4 700.00 Dallas (TX) TX 75001 7 37
234 176781 Lightning Charging Cable 1 14.95 2019-04-03 07:37:00 976 Hickory St, Dallas, TX 75001 4 14.95 Dallas (TX) TX 75001 7 37

Les données avec le même identifiant sont désormais alignées sur une ligne

L'ensemble de données ci-dessus est la commande avec l'ID (≒ rien d'autre que la commande achetée en tant qu'ensemble)

Après le regroupement par ID, créez une colonne qui stocke les commandes achetées par cet ID. (Exemple ID: 1111 → Commande: pomme, banane, orange)

df = all_data[all_data['Order ID'].duplicated(keep=False)]
df['Grouped'] = df.groupby('Order ID')['Product'].transform(lambda x: ','.join(x))
#transform est comme une fonction Apply. Je vais omettre l'explication ici.
df = df[['Order ID','Grouped']].drop_duplicates()
df.head(10)
/opt/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:2: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
Order ID Grouped
3 176560 Google Phone,Wired Headphones
18 176574 Google Phone,USB-C Charging Cable
30 176585 Bose SoundSport Headphones,Bose SoundSport Hea...
32 176586 AAA Batteries (4-pack),Google Phone
119 176672 Lightning Charging Cable,USB-C Charging Cable
129 176681 Apple Airpods Headphones,ThinkPad Laptop
138 176689 Bose SoundSport Headphones,AAA Batteries (4-pack)
189 176739 34in Ultrawide Monitor,Google Phone
225 176774 Lightning Charging Cable,USB-C Charging Cable
233 176781 iPhone,Lightning Charging Cable

Ça fait du bien. Les données sont bien organisées.

Dans cette colonne groupée, vous devez rechercher "qui, qui, dans quelle combinaison, combien de fois" etc.

Agrégons tout en utilisant une bibliothèque pratique. Voir stackoverflow ci-dessous pour une image concrète de la bibliothèque.

from itertools import combinations
from collections import Counter

count = Counter()
for row in df['Grouped']:
    row_list = row.split(',')
    count.update(Counter(combinations(row_list,2)))
    
count.most_common(10)
[(('iPhone', 'Lightning Charging Cable'), 1005),
 (('Google Phone', 'USB-C Charging Cable'), 987),
 (('iPhone', 'Wired Headphones'), 447),
 (('Google Phone', 'Wired Headphones'), 414),
 (('Vareebadd Phone', 'USB-C Charging Cable'), 361),
 (('iPhone', 'Apple Airpods Headphones'), 360),
 (('Google Phone', 'Bose SoundSport Headphones'), 220),
 (('USB-C Charging Cable', 'Wired Headphones'), 160),
 (('Vareebadd Phone', 'Wired Headphones'), 143),
 (('Lightning Charging Cable', 'Wired Headphones'), 92)]

La sortie est un peu sale, donc je vais faire des corrections mineures

for key,value in count.most_common(10):
    print(key,value)
('iPhone', 'Lightning Charging Cable') 1005
('Google Phone', 'USB-C Charging Cable') 987
('iPhone', 'Wired Headphones') 447
('Google Phone', 'Wired Headphones') 414
('Vareebadd Phone', 'USB-C Charging Cable') 361
('iPhone', 'Apple Airpods Headphones') 360
('Google Phone', 'Bose SoundSport Headphones') 220
('USB-C Charging Cable', 'Wired Headphones') 160
('Vareebadd Phone', 'Wired Headphones') 143
('Lightning Charging Cable', 'Wired Headphones') 92

iPhone et câble de charge sont les plus

Travail 5 (travail final): quel produit est le plus vendu? Pourquoi pensez-vous qu'il se vend le mieux?

C'est le dernier travail. Vous en êtes venu à penser par vous-même (partie hypothèse). Visualisons les données.

Pensez en quantité

product_group = all_data.groupby('Product')
quantity_ordered = product_group.sum()['Quantity Ordered']
products = [product for product,df in product_group]
plt.bar(products,quantity_ordered)
plt.xlabel('Product')
plt.ylabel('Quantity Ordered')
plt.xticks(products,rotation="vertical",size=8)
plt.show()

output_3.png

Y a-t-il beaucoup de câbles de batterie?

Je suppose que c'est parce que le prix est bon marché. Vérifiez les prix et les ventes.

prices = all_data.groupby('Product').mean()['Price Each']

fig, ax1 = plt.subplots()

ax2 = ax1.twinx()
#Génération de graphique commune à l'axe x et ayant différentes valeurs d'axe y
ax1.bar(products,quantity_ordered)
ax2.plot(products,prices,'b-')

ax1.set_xlabel('Product Name')
ax1.set_ylabel('Quanity Ordered', color="g")
ax2.set_ylabel('Price', color="b")
ax1.set_xticklabels(products,rotation="vertical",size=8)

plt.show()

output_4.png

C'est tout.

Recommended Posts

[Pandas] J'ai essayé d'analyser les données de ventes avec Python [Pour les débutants]
J'ai essayé d'obtenir des données CloudWatch avec Python
Je veux pouvoir analyser des données avec Python (partie 3)
J'ai essayé de créer diverses "données factices" avec Python faker
Je veux pouvoir analyser des données avec Python (partie 1)
Je veux pouvoir analyser des données avec Python (partie 4)
[Pour les professionnels de la compétition débutants] J'ai essayé de résoudre 40 questions AOJ "ITP I" avec python
J'ai essayé de créer un cadre de données pandas en grattant les informations de rappel d'aliments avec Python
Je veux analyser les journaux avec Python
J'ai essayé de résoudre l'édition du débutant du livre des fourmis avec python
J'ai essayé de sauvegarder les données avec discorde
J'ai essayé de sortir LLVM IR avec Python
J'ai essayé d'automatiser la fabrication des sushis avec python
[Bases de la science des données] J'ai essayé d'enregistrer de csv à mysql avec python
J'ai essayé l'analyse de données IRMf avec python (Introduction au décodage des informations cérébrales)
Analysons les données Covid-19 (Corona) en utilisant Python [Pour les débutants]
J'ai essayé fp-growth avec python
J'ai essayé de gratter avec Python
[Pour les débutants] Comment étudier le test d'analyse de données Python3
J'ai essayé d'implémenter Mine Sweeper sur un terminal avec python
J'ai essayé de démarrer avec le script python de blender_Part 01
J'ai essayé de toucher un fichier CSV avec Python
J'ai essayé de résoudre Soma Cube avec python
J'ai essayé d'implémenter le perceptron artificiel avec python
J'ai essayé d'obtenir et d'analyser les données statistiques de la nouvelle Corona avec Python: données de l'Université John's Hopkins
J'ai essayé de résumer comment utiliser les pandas de python
Pandas 100 coups pour les débutants en Python
J'ai essayé de résoudre le problème avec Python Vol.1
J'ai essayé gRPC avec Python
J'ai essayé de gratter avec du python
~ Conseils pour les débutants de Python présentés avec amour par Pythonista ③ ~
J'ai essayé de résoudre la théorie des nombres entiers d'AOJ avec Python
Pour ceux qui débutent en programmation mais qui ont décidé d'analyser les données avec Python
J'ai essayé d'agréger et de comparer les données de prix unitaires par langue avec Real Gachi by Python
J'ai essayé de comparer la vitesse de traitement avec dplyr de R et pandas de Python
J'ai essayé de créer un environnement d'apprentissage automatique avec Python (Mac OS X)
J'ai essayé d'analyser les émotions de tout le roman "Weather Child" ☔️
J'ai essayé différentes méthodes pour envoyer du courrier japonais avec Python
[Introduction à Pandas] J'ai essayé d'augmenter les données d'échange par interpolation de données ♬
[Python] J'ai essayé de visualiser des tweets sur Corona avec WordCloud
Mayungo's Python Learning Episode 3: J'ai essayé d'imprimer des nombres
[Python] Introduction à la création de graphiques à l'aide de données de virus corona [Pour les débutants]
J'ai essayé de créer une interface graphique à trois yeux côte à côte avec Python et Tkinter
J'ai essayé d'analyser les données scRNA-seq en utilisant l'analyse des données topologiques (TDA)
J'ai essayé de toucher Python (installation)
Je veux faire ○○ avec les Pandas
Je veux déboguer avec Python
J'ai essayé d'exécuter prolog avec python 3.8.2.
les débutants en python ont essayé de le découvrir
J'ai essayé la communication SMTP avec Python
J'en ai marre de Python, alors j'ai essayé d'analyser les données avec nehan (je veux aller vivre même avec Corona) -Partie 2)
J'en ai marre de Python, alors j'ai essayé d'analyser les données avec nehan (je veux aller vivre même avec Corona) -Partie 1)
J'ai essayé d'analyser les données du tournoi de football de la Coupe du monde de football en Russie avec l'action de football
[3ème] J'ai essayé de créer un certain outil de type Authenticator avec python
[Python] Un mémo que j'ai essayé de démarrer avec asyncio
J'ai essayé de corriger "J'ai essayé la simulation probabiliste du jeu de bingo avec Python"