[PYTHON] C'est pourquoi j'ai quitté les pandas [Data Science 100 Knock (traitement des données structurées) # 1]

C'est pourquoi j'ai quitté les pandas [Data Science 100 Knock (traitement des données structurées) # 1]

Nous allons résoudre le problème Python de Data Science 100 Knock (traitement des données structurées). Ce groupe de questions utilise des pandas pour le traitement des données dans la réponse du modèle, mais nous le traiterons en utilisant le tableau structuré de NumPy après étude.

: arrow_forward: Article suivant (# 2)

introduction

Beaucoup de gens qui font des activités de science des données en Python sont peut-être des amateurs de pandas, mais en fait, vous pouvez faire de même avec NumPy sans utiliser ** pandas **. Et NumPy est généralement plus rapide. En tant que personne qui aime les pandas, je ne suis toujours pas habitué à utiliser NumPy, donc j'aimerais essayer de sortir des pandas en exploitant ce "Data Science 100 Knock" avec NumPy.

Cette fois, je répondrai à la huitième question. Il semble que seul reception.csv soit utilisé cette fois. Les données initiales ont été lues comme suit (la spécification du type de données est pour le moment reportée).

import numpy as np
import pandas as pd

#Pour la réponse du modèle
df_receipt = pd.read_csv('data/receipt.csv')

#Données que nous traitons
arr_receipt = np.genfromtxt(
    'data/receipt.csv', delimiter=',', encoding='utf-8',
    names=True, dtype=None)

C'est une économie de mémoire.

import sys

sys.getsizeof(df_receipt)
# 26065721
sys.getsizeof(arr_receipt)
# 15074160

P_001

P-001: Affichez les 10 premiers éléments de tous les éléments du bloc de données (df_receipt) des détails du reçu et vérifiez visuellement le type de données dont vous disposez.

Prenez-le en tranches.

In[001]


arr_receipt[:10]

Vous pouvez obtenir les données comme suit. De plus, il est assez intelligent d'aligner les virgules (à moins qu'il n'y ait une chaîne de caractères pleine largeur).

Out[001]


array([(20181103, 1257206400, 'S14006',  112, 1, 'CS006214000001', 'P070305012', 1, 158),
       (20181118, 1258502400, 'S13008', 1132, 2, 'CS008415000097', 'P070701017', 1,  81),
       (20170712, 1215820800, 'S14028', 1102, 1, 'CS028414000014', 'P060101005', 1, 170),
       (20190205, 1265328000, 'S14042', 1132, 1, 'ZZ000000000000', 'P050301001', 1,  25),
       (20180821, 1250812800, 'S14025', 1102, 2, 'CS025415000050', 'P060102007', 1,  90),
       (20190605, 1275696000, 'S13003', 1112, 1, 'CS003515000195', 'P050102002', 1, 138),
       (20181205, 1259971200, 'S14024', 1102, 2, 'CS024514000042', 'P080101005', 1,  30),
       (20190922, 1285113600, 'S14040', 1102, 1, 'CS040415000178', 'P070501004', 1, 128),
       (20170504, 1209859200, 'S13020', 1112, 2, 'ZZ000000000000', 'P071302010', 1, 770),
       (20191010, 1286668800, 'S14027', 1102, 1, 'CS027514000015', 'P071101003', 1, 680)],
      dtype=[('sales_ymd', '<i4'), ('sales_epoch', '<i4'), ('store_cd', '<U6'), ('receipt_no', '<i4'), ('receipt_sub_no', '<i4'), ('customer_id', '<U14'), ('product_cd', '<U10'), ('quantity', '<i4'), ('amount', '<i4')])

Comparons la vitesse avec la réponse du modèle (pandas).

Time[001]


#Le modèle de réponse
%timeit df_receipt.head(10)
# 130 µs ± 5.02 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

%timeit arr_receipt[:10]
# 244 ns ± 8.23 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

J'ai pu l'obtenir à 1/500 de la vitesse de réponse du modèle.

P_002

P-002: indiquez les colonnes dans l'ordre de la date de vente (sales_ymd), de l'ID client (customer_id), du code produit (product_cd) et du montant des ventes (montant) à partir du bloc de données du relevé de réception (df_receipt) et affichez 10 éléments.

Le tableau structuré de NumPy peut être manipulé de la même manière que le pd.DataFrame auquel nous sommes habitués.

In[002]


arr_receipt[['sales_ymd', 'customer_id', 'product_cd', 'amount']][:10]

Out[002]


array([(20181103, 'CS006214000001', 'P070305012', 158),
       (20181118, 'CS008415000097', 'P070701017',  81),
       (20170712, 'CS028414000014', 'P060101005', 170),
       (20190205, 'ZZ000000000000', 'P050301001',  25),
       (20180821, 'CS025415000050', 'P060102007',  90),
       (20190605, 'CS003515000195', 'P050102002', 138),
       (20181205, 'CS024514000042', 'P080101005',  30),
       (20190922, 'CS040415000178', 'P070501004', 128),
       (20170504, 'ZZ000000000000', 'P071302010', 770),
       (20191010, 'CS027514000015', 'P071101003', 680)],
      dtype={'names':['sales_ymd','customer_id','product_cd','amount'], 'formats':['<i4','<U14','<U10','<i4'], 'offsets':[0,40,96,140], 'itemsize':144})

Plus rapide que de manipuler pd.DataFrame.

Time[002]


%timeit df_receipt[['sales_ymd', 'customer_id', 'product_cd', 'amount']].head(10)
# 5.19 ms ± 43.5 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit arr_receipt[['sales_ymd', 'customer_id', 'product_cd', 'amount']][:10]
# 906 ns ± 17.5 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

P_003

P-003: indiquez les colonnes dans l'ordre de la date de vente (sales_ymd), de l'ID client (customer_id), du code produit (product_cd), du montant des ventes (montant) à partir du bloc de données du relevé de réception (df_receipt) et affichez 10 articles. Cependant, sales_ymd doit être extrait lors du changement du nom de l'article en sales_date.

Renommer est une chose simple et ennuyeuse. Il est plus facile de passer par np.lib.recfunctions.rename_fields (), mais cette fonction est encore assez difficile à utiliser.

In[003]


np.lib.recfunctions.rename_fields(arr_receipt, {'sales_ymd': 'sales_date'})[
    ['sales_date', 'customer_id', 'product_cd', 'amount']][:10]

Out[003]


array([(20181103, 'CS006214000001', 'P070305012', 158),
       (20181118, 'CS008415000097', 'P070701017',  81),
       (20170712, 'CS028414000014', 'P060101005', 170),
       (20190205, 'ZZ000000000000', 'P050301001',  25),
       (20180821, 'CS025415000050', 'P060102007',  90),
       (20190605, 'CS003515000195', 'P050102002', 138),
       (20181205, 'CS024514000042', 'P080101005',  30),
       (20190922, 'CS040415000178', 'P070501004', 128),
       (20170504, 'ZZ000000000000', 'P071302010', 770),
       (20191010, 'CS027514000015', 'P071101003', 680)],
      dtype={'names':['sales_date','customer_id','product_cd','amount'], 'formats':['<i4','<U14','<U10','<i4'], 'offsets':[0,40,96,140], 'itemsize':144})

Cependant, il traite très rapidement par rapport aux pandas.

Time[003]


%timeit df_receipt[['sales_ymd', 'customer_id', 'product_cd', 'amount']].rename(columns={'sales_ymd': 'sales_date'}).head(10)
# 12.8 ms ± 252 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit np.lib.recfunctions.rename_fields(arr_receipt, {'sales_ymd': 'sales_date'})[['sales_date', 'customer_id', 'product_cd', 'amount']][:10]
# 6.19 µs ± 132 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

C'est lent et lourd parce que les pandas créent de nouveaux objets de trame de données à chaque fois qu'ils traitent.

P_004

P-004: Données qui remplissent les conditions suivantes en spécifiant les colonnes dans l'ordre de la date de vente (sales_ymd), de l'ID client (customer_id), du code produit (product_cd) et du montant des ventes (montant) à partir du cadre de données du relevé de réception (df_receipt). Extrait.

  • L'ID client (id_client) est "CS018205000001"

Ceci peut également être obtenu par une utilisation intuitive.

In[004]


arr_receipt[['sales_ymd', 'customer_id', 'product_cd', 'amount']][
    arr_receipt['customer_id'] == 'CS018205000001']

Out[004]


arr_receipt[['sales_ymd','customer_id','product_cd','amount']][arr_receipt['customer_id'] == 'CS018205000001']
array([(20180911, 'CS018205000001', 'P071401012', 2200),
       (20180414, 'CS018205000001', 'P060104007',  600),
       (20170614, 'CS018205000001', 'P050206001',  990),
       (20170614, 'CS018205000001', 'P060702015',  108),
       (20190216, 'CS018205000001', 'P071005024',  102),
       (20180414, 'CS018205000001', 'P071101002',  278),
       (20190226, 'CS018205000001', 'P070902035',  168),
       (20190924, 'CS018205000001', 'P060805001',  495),
       (20190226, 'CS018205000001', 'P071401020', 2200),
       (20180911, 'CS018205000001', 'P071401005', 1100),
       (20190216, 'CS018205000001', 'P040101002',  218),
       (20190924, 'CS018205000001', 'P091503001',  280)],
      dtype={'names':['sales_ymd','customer_id','product_cd','amount'], 'formats':['<i4','<U14','<U10','<i4'], 'offsets':[0,40,96,140], 'itemsize':144})

La réponse du modèle semble aimer «pd.DataFrame.query ()». Je pense qu'il devrait être indexé normalement.

Time[004]


%timeit df_receipt[['sales_ymd', 'customer_id', 'product_cd', 'amount']].query('customer_id == "CS018205000001"')
# 11.6 ms ± 477 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit df_receipt.loc[df_receipt['customer_id'] == 'CS018205000001', ['sales_ymd', 'customer_id', 'product_cd', 'amount']]
# 9.49 ms ± 212 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit arr_receipt[['sales_ymd', 'customer_id', 'product_cd', 'amount']][arr_receipt['customer_id'] == 'CS018205000001']
# 2.7 ms ± 475 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

P_005

P-005: Données qui remplissent les conditions suivantes en spécifiant les colonnes dans l'ordre de la date de vente (sales_ymd), de l'ID client (customer_id), du code produit (product_cd) et du montant des ventes (montant) à partir du bloc de données du relevé de réception (df_receipt). Extrait.

  • L'ID client (id_client) est "CS018205000001" --Le montant des ventes (montant) est de 1000 ou plus

C'est la même chose même s'il y a plusieurs conditions.

In[005]


arr_receipt[['sales_ymd', 'customer_id', 'product_cd', 'amount']][
    (arr_receipt['customer_id'] == 'CS018205000001') & (arr_receipt['amount'] >= 1000)]

Out[005]


array([(20180911, 'CS018205000001', 'P071401012', 2200),
       (20190226, 'CS018205000001', 'P071401020', 2200),
       (20180911, 'CS018205000001', 'P071401005', 1100)],
      dtype={'names':['sales_ymd','customer_id','product_cd','amount'], 'formats':['<i4','<U14','<U10','<i4'], 'offsets':[0,40,96,140], 'itemsize':144})

P_006

P-006: indiquez les colonnes dans l'ordre de la date de vente (sales_ymd), de l'ID client (customer_id), du code produit (product_cd), de la quantité des ventes (quantité), du montant des ventes (montant) à partir du cadre de données de détail du reçu "df_receipt", puis Extraire les données qui remplissent les conditions de.

  • L'ID client (id_client) est "CS018205000001"
  • Le montant des ventes (montant) est de 1000 ou plus ou la quantité des ventes (quantité) est de 5 ou plus

D'une manière ou d'une autre, la ligne s'allonge, alors je vais la diviser.

In[006]


col_list = ['sales_ymd', 'customer_id', 'product_cd', 'quantity', 'amount']
cond = ((arr_receipt['customer_id'] == 'CS018205000001')
        & ((arr_receipt['amount'] >= 1000) | (arr_receipt['quantity'] >= 5)))

arr_receipt[col_list][cond]

Out[006]


array([(20180911, 'CS018205000001', 'P071401012', 2200),
       (20180414, 'CS018205000001', 'P060104007',  600),
       (20170614, 'CS018205000001', 'P050206001',  990),
       (20190226, 'CS018205000001', 'P071401020', 2200),
       (20180911, 'CS018205000001', 'P071401005', 1100)],
      dtype={'names':['sales_ymd','customer_id','product_cd','amount'], 'formats':['<i4','<U14','<U10','<i4'], 'offsets':[0,40,96,140], 'itemsize':144})

P_007

P-007: Données qui remplissent les conditions suivantes en spécifiant les colonnes dans l'ordre de la date de vente (sales_ymd), de l'ID client (customer_id), du code produit (product_cd) et du montant des ventes (montant) à partir du cadre de données du relevé de réception (df_receipt). Extrait.

  • L'ID client (id_client) est "CS018205000001"
  • Le montant (montant) des ventes est de 1000 ou plus et de 2000 ou moins

In[007]


col_list = ['sales_ymd', 'customer_id', 'product_cd', 'quantity', 'amount']
cond = ((arr_receipt['customer_id'] == 'CS018205000001')
        & ((1000 <= arr_receipt['amount']) & (arr_receipt['amount'] <= 2000)))

arr_receipt[col_list][cond]

Out[007]


array([(20180911, 'CS018205000001', 'P071401005', 1, 1100)],
      dtype={'names':['sales_ymd','customer_id','product_cd','quantity','amount'], 'formats':['<i4','<U14','<U10','<i4','<i4'], 'offsets':[0,40,96,136,140], 'itemsize':144})

P_008

P-008: Données qui remplissent les conditions suivantes en spécifiant les colonnes dans l'ordre de la date de vente (sales_ymd), de l'ID client (customer_id), du code produit (product_cd) et du montant des ventes (montant) à partir du cadre de données du relevé de réception (df_receipt). Extrait.

  • L'ID client (id_client) est "CS018205000001"
  • Le code produit (product_cd) est autre que "P071401019"

In[008]


col_list = ['sales_ymd', 'customer_id', 'product_cd', 'quantity', 'amount']
cond = ((arr_receipt['customer_id'] == 'CS018205000001')
        & (arr_receipt['product_cd'] != 'P071401019'))

arr_receipt[col_list][cond]

Out[008]


array([(20180911, 'CS018205000001', 'P071401012', 1, 2200),
       (20180414, 'CS018205000001', 'P060104007', 6,  600),
       (20170614, 'CS018205000001', 'P050206001', 5,  990),
       (20170614, 'CS018205000001', 'P060702015', 1,  108),
       (20190216, 'CS018205000001', 'P071005024', 1,  102),
       (20180414, 'CS018205000001', 'P071101002', 1,  278),
       (20190226, 'CS018205000001', 'P070902035', 1,  168),
       (20190924, 'CS018205000001', 'P060805001', 1,  495),
       (20190226, 'CS018205000001', 'P071401020', 1, 2200),
       (20180911, 'CS018205000001', 'P071401005', 1, 1100),
       (20190216, 'CS018205000001', 'P040101002', 1,  218),
       (20190924, 'CS018205000001', 'P091503001', 1,  280)],
      dtype={'names':['sales_ymd','customer_id','product_cd','quantity','amount'], 'formats':['<i4','<U14','<U10','<i4','<i4'], 'offsets':[0,40,96,136,140], 'itemsize':144})

Time[008]


col_list = ['sales_ymd', 'customer_id', 'product_cd', 'quantity', 'amount']

%timeit df_receipt[col_list].query('customer_id == "CS018205000001" & product_cd != "P071401019"')
# 15.6 ms ± 1.19 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

%timeit arr_receipt[col_list][((arr_receipt['customer_id'] == 'CS018205000001') & (arr_receipt['product_cd'] != 'P071401019'))]
# 4.28 ms ± 86.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

en conclusion

Hey Il s'agit d'un traitement de données ultra-rapide et ultra-rapide réalisé avec NumPy. Vous pouvez le cracher sur csv après le traitement, et les pandas ne feront pas de traitement lourd. Alors j'ai quitté les pandas

Recommended Posts

C'est pourquoi j'ai quitté les pandas [Data Science 100 Knock (traitement des données structurées) # 2]
C'est pourquoi j'ai quitté les pandas [Data Science 100 Knock (traitement des données structurées) # 1]
C'est pourquoi j'ai quitté les pandas [Data Science 100 Knock (traitement des données structurées) # 3]
C'est pourquoi j'ai quitté les pandas [Data Science 100 Knock (traitement des données structurées) # 5]
C'est pourquoi j'ai quitté les pandas [Data Science 100 Knock (traitement des données structurées) # 4]
C'est pourquoi j'ai quitté les pandas [Data Science 100 Knock (traitement des données structurées) # 6]
"Data Science 100 Knock (traitement de données structurées)" Explication Python-007
"Data Science 100 Knock (traitement des données structurées)" Explication Python-006
"Data Science 100 Knock (traitement des données structurées)" Explication Python-001
"Data Science 100 Knock (traitement des données structurées)" Explication Python-002
[Python] 100 coups sur la science des données (traitement de données structurées) 021 Explication
"Data Science 100 Knock (traitement des données structurées)" Explication Python-005
"Data Science 100 Knock (traitement de données structurées)" Explication Python-004
[Python] 100 coups sur la science des données (traitement de données structurées) 020 Explication
[Python] 100 coups sur la science des données (traitement de données structurées) 025 Explication
"Data Science 100 Knock (traitement des données structurées)" Explication Python-003
[Python] 100 coups sur la science des données (traitement de données structurées) 019 Explication
Préparation à l’essai de «Data Science 100 Knock (traitement des données structurées)»
Construction d'environnement (Windows 10) pour 100 coups de science des données (traitement de données structurées)
[Python] 100 coups sur la science des données (traitement de données structurées) 001-010 Impressions + résumé du lien de commentaire
C'est pourquoi j'ai quitté pandas [Trois façons de groupby.mean () avec juste NumPy]
[Python] 100 coups sur la science des données (traitement de données structurées) 018 Explication
[Python] 100 coups sur la science des données (traitement de données structurées) 023 Explication
[Python] 100 coups sur la science des données (traitement de données structurées) 030 Explication
[Python] 100 coups sur la science des données (traitement de données structurées) 022 Explication
100 langage de traitement knock-20 (à l'aide de pandas): lecture de données JSON
[Python] 100 coups sur la science des données (traitement de données structurées) 017 Explication
[Python] 100 coups sur la science des données (traitement de données structurées) 026 Explication
[Python] 100 coups sur la science des données (traitement de données structurées) 016 Explication
[Python] 100 coups sur la science des données (traitement de données structurées) 024 Explication
[Python] 100 coups sur la science des données (traitement de données structurées) 027 Explication
[Python] 100 coups sur la science des données (traitement de données structurées) 029 Explication
[Python] 100 coups sur la science des données (traitement de données structurées) 015 Explication
[Python] 100 coups sur la science des données (traitement de données structurées) 028 Explication
Commentaire sur la science des données à 100 coups (P021 ~ 040)
Commentaire sur la science des données à 100 coups (P061 ~ 080)
Commentaire sur la science des données à 100 coups (P081 ~ 100)
J'ai essayé 100 traitements linguistiques Knock 2020
Conseils de traitement des données avec Pandas
J'ai essayé 100 traitements linguistiques Knock 2020: Chapitre 3
100 traitement du langage knock-31 (en utilisant des pandas): verbe
J'ai essayé 100 traitements linguistiques Knock 2020: Chapitre 1
J'ai essayé 100 traitements linguistiques Knock 2020: Chapitre 2
J'ai essayé 100 traitements linguistiques Knock 2020: Chapitre 4
100 traitement du langage knock-38 (en utilisant des pandas): histogramme
100 Language Processing Knock-33 (en utilisant des pandas): nom sahen
J'ai essayé la "Practical Python Data Science" d'Udemy
100 traitement du langage knock-35 (utilisant des pandas): concaténation de nomenclature
100 Language Processing Knock-39 (en utilisant des pandas): la loi de Zipf
Exemple de traitement efficace des données avec PANDAS
100 traitement de langage knock-34 (utilisant des pandas): "B of A"