¿Quién fabrica lo que compramos?
08 Feb 2017Los códigos de barras de los productos que compramos contienen información sobre la empresa que los distribuye, empaca o fabrica. En este breve ejercicio, vamos a intentar combinar una lista de productos tomada del sitio público Precios Claros con una lista de compañías compilada por el proyecto Product Open Data.
Los identificadores de productos en preciosclaros.gob.ar son, en la mayoría de los casos, el código de barras del producto. Para extraer el campo GCP (Global Company Prefix) del identificador, vamos a usar la librería gtin
.
import pandas as pd
from gtin import GTIN
Leemos la lista de productos, y agradecemos a nuestro anónimo amigo que se tomó el trabajo de scrapear Precios Claros.
df = pd.read_csv('productos_precios_claros.csv')
df.loc[:, 'uuid'] = df.uuid.apply(lambda s: s.split('producto-')[1])
Agregamos una columna que contendrá, si es posible, el campo GCP.
def gg(gtin):
try:
g = GTIN(gtin)
except:
return None
try:
return g.get_gcp()
except:
return None
df.loc[:, 'gcp'] = df.uuid.apply(lambda u: gg(u))
Calculamos una agregación de la tabla anterior, calculando dos variables adicionales:
marca
: un conjunto de marcas asociadas a unGCP
product_count
: cantidad de productos asociados a unGCP
products_by_gcp = df \
.groupby(['gcp'], as_index=False) \
.agg({
'marca': lambda m: set(m),
'uuid': 'count'
}) \
.rename(columns={'uuid': 'product_count'}) \
.sort_values(by='product_count', ascending=False)
Leemos la base de datos de GCPs obtenida de Product Open Data. Lamentablemente, la última versión es de 2013 y su cobertura para fabricantes argentinos es bastante mala.
gepir = pd.read_csv('/Users/manuel/Downloads/gs1_gcp.csv',
dtype={'GCP_CD': str, 'GLN_CD': str},
low_memory=False)
…y la combinamos con nuestra lista de GCPs (products_by_gcp
).
merged = products_by_gcp.merge(gepir, how='inner', left_on='gcp', right_on='GCP_CD')
Verificamos qué porcentaje de GCPs pudimos encontrar en la base de datos:
n_matched_gcps = len(merged[~merged.GLN_NM.isnull()])
total_gcps = len(products_by_gcp)
print((n_matched_gcps / total_gcps) * 100)
66.34615384615384
Filtramos la lista para mostrar solamente las compañías que pudimos encontrar
out = merged[~merged.GLN_NM.isnull()][['gcp', 'product_count', 'marca', 'GLN_NM', 'GLN_COUNTRY_ISO_CD']]
Le agregamos la bandera del país para que quede más cheto.
OFFSET = ord('🇦') - ord('A')
def flag(code):
return chr(ord(code[0]) + OFFSET) + chr(ord(code[1]) + OFFSET)
out.loc[:, 'country_flag'] = out['GLN_COUNTRY_ISO_CD'].apply(flag)
pd.set_option('display.max_rows', len(out))
out
gcp | product_count | marca | GLN_NM | GLN_COUNTRY_ISO_CD | country_flag | |
---|---|---|---|---|---|---|
0 | 8480017 | 1009 | {GROLS, CUQUE, NAN, CARO AMICI, S.OND, CROCK, ... | DIA | ES | 🇪🇸 |
2 | 4005808 | 29 | {NIVEA} | Beiersdorf AG | DE | 🇩🇪 |
3 | 0070330 | 18 | {BIC , BIC} | BIC USA Inc. | US | 🇺🇸 |
5 | 4052899 | 10 | {OSRAM, DULUX} | OSRAM GmbH CRM&S MDS P-W | DE | 🇩🇪 |
6 | 301426 | 10 | {ZOOTH, GILLETTE, ORAL B} | PROCTER ET GAMBLE FRANCE SAS | FR | 🇫🇷 |
9 | 75010074 | 7 | {KOLESTON, ALWAYS, PANTENE} | CORPORATIVO PROCTER & GAMBLE, S. DE R.L. DE C.... | MX | 🇲🇽 |
10 | 4008321 | 7 | {OSRAM, DULUX} | OSRAM GmbH | DE | 🇩🇪 |
12 | 75010067 | 6 | {PAMPERS, PANTENE} | CORPORATIVO PROCTER & GAMBLE, S. DE R.L. DE C.... | MX | 🇲🇽 |
13 | 7509546 | 6 | {PROTEX, COLGATE, PALMOLIVE} | COLGATE PALMOLIVE, S.A. DE C.V. COLGATE PALMOLIVE | MX | 🇲🇽 |
14 | 0038000 | 6 | {PRINGLES} | Kellogg Company | US | 🇺🇸 |
15 | 8413600 | 5 | {VEET} | RECKITT BENCKISER | ES | 🇪🇸 |
16 | 0047400 | 5 | {GILLETTE} | Procter & Gamble Company | US | 🇺🇸 |
17 | 75010092 | 5 | {GILLETTE, PRESTOBARBA} | NEWELL RUBBERMAID DE MEXICO, S. DE R.L. DE C.V... | MX | 🇲🇽 |
18 | 75010563 | 5 | {PONDS, SEDAL} | UNILEVER DE MEXICO, S. DE R.L. DE C.V. UNILEVER | MX | 🇲🇽 |
19 | 4005900 | 5 | {NIVEA} | Beiersdorf AG | DE | 🇩🇪 |
20 | 0041789 | 5 | {MARUCHAN} | Maruchan, Inc. | US | 🇺🇸 |
21 | 75010592 | 4 | {COFFEE MATE, NESCAFE} | NESTLE MEXICO, S.A. DE C.V. NESTLE MEXICO, S.A... | MX | 🇲🇽 |
22 | 0000075 | 4 | {CORONA, DOVE, REXONA} | ASOCIACION MEXICANA DE ESTANDARES PARA EL COME... | MX | 🇲🇽 |
23 | 0041333 | 4 | {DURAC} | Procter & Gamble Company | US | 🇺🇸 |
24 | 0084773 | 4 | {ROBINSON CRUSOE} | Trans Antartic Trading Co Ltda | CL | 🇨🇱 |
25 | 8718291 | 3 | {PHILI} | Philips Electronics Nederland B.V. | NL | 🇳🇱 |
26 | 75010011 | 3 | {HEAD & SHOULDERS, PANTENE} | CORPORATIVO PROCTER & GAMBLE, S. DE R.L. DE C.... | MX | 🇲🇽 |
27 | 0040000 | 3 | {M & M, SKITTLES} | Mars Chocolate North America LLC | US | 🇺🇸 |
29 | 8710163 | 3 | {PHILI} | Philips Electronics Nederland B.V. | NL | 🇳🇱 |
30 | 8710103 | 3 | {PHILI} | Philips Electronics Nederland B.V. | NL | 🇳🇱 |
31 | 0000080 | 3 | {KINDER} | Indicod-Ecr - GS1 Italy | IT | 🇮🇹 |
32 | 75010086 | 2 | {BACARDI} | BACARDI Y COMPAÑIA, S.A. DE C.V. BACARDI | MX | 🇲🇽 |
33 | 75010012 | 2 | {HEAD & SHOULDERS} | CORPORATIVO PROCTER & GAMBLE, S. DE R.L. DE C.... | MX | 🇲🇽 |
34 | 75010013 | 2 | {OLD SPICE, PANTENE} | CORPORATIVO PROCTER & GAMBLE, S. DE R.L. DE C.... | MX | 🇲🇽 |
35 | 9044400 | 2 | {PEZ} | PEZ International GmbH | AT | 🇦🇹 |
36 | 8712581 | 2 | {PHILI} | Philips Electronics Nederland B.V. | NL | 🇳🇱 |
37 | 75010864 | 2 | {PRO} | CORPORATIVO PROCTER & GAMBLE, S. DE R.L. DE C.... | MX | 🇲🇽 |
38 | 7591083 | 2 | {COLGATE} | COLGATE-PALMOLIVE C.A | VE | 🇻🇪 |
39 | 0021200 | 2 | {SCOTCH BRITE} | 3M Company | US | 🇺🇸 |
41 | 0071603 | 2 | {TRIM} | Pacific World Corporation | US | 🇺🇸 |
42 | 08452180 | 2 | {VULCA, SIN MARCA} | GS1 China | CN | 🇨🇳 |
43 | 0070501 | 2 | {NEUTROGENA} | Neutrogena Corporation | US | 🇺🇸 |
44 | 0022000 | 2 | {WRIGLEYS} | Wm. Wrigley Jr. Company | US | 🇺🇸 |
45 | 4015400 | 2 | {PAMPERS} | Procter & Gamble GmbH Wasch- u. Reinigungsmittel | DE | 🇩🇪 |
46 | 0079400 | 2 | {REXONA} | Unilever Home and Personal Care USA | US | 🇺🇸 |
47 | 5000329 | 2 | {BEEFEATER} | Chivas Brothers Limited | GB | 🇬🇧 |
48 | 0012800 | 1 | {RAYOV} | Spectrum Brands, Inc. | US | 🇺🇸 |
49 | 9002490 | 1 | {RED BULL} | Red Bull GmbH | AT | 🇦🇹 |
50 | 0079200 | 1 | {NERDS} | Sunmark | US | 🇺🇸 |
51 | 0000040 | 1 | {KINDER} | Nestlé Deutschland AG | DE | 🇩🇪 |
52 | 0070942 | 1 | {GUM} | Sunstar Americas, Inc. | US | 🇺🇸 |
53 | 8412300 | 1 | {NIVEA} | BEIERSDORF MANUFACTURING TRES CANTO | ES | 🇪🇸 |
54 | 8715200 | 1 | {NIVEA} | Beiersdorf N.V. | NL | 🇳🇱 |
55 | 0051000 | 1 | {sin marca} | Campbell Soup Company | US | 🇺🇸 |
57 | 0080432 | 1 | {CHIVAS REGAL} | Pernod Ricard USA LLC | US | 🇺🇸 |
58 | 0016304 | 1 | {SIN MARCA} | Unofficial Guides Ltd. | US | 🇺🇸 |
59 | 0013000 | 1 | {HEINZ} | Heinz USA | US | 🇺🇸 |
60 | 0099176 | 1 | {COLGATE} | Colgate Palmolive (Central America) S.A. | GT | 🇬🇹 |
61 | 0090159 | 1 | {MAIST} | May Cheong Toy Products Factory Limited | HK | 🇭🇰 |
62 | 75010587 | 1 | {sin marca} | RECKITT BENCKISER MEXICO, S.A. DE C.V. RECKITT... | MX | 🇲🇽 |
63 | 5900273 | 1 | {COLGATE} | Colgate-Palmolive (Poland) Sp. z o.o. | PL | 🇵🇱 |
64 | 5410316 | 1 | {SMIRNOFF} | DIAGEO SCOTLAND LTD | GB | 🇬🇧 |
65 | 5011013 | 1 | {BAILEYS} | GS1 Ireland | IE | 🇮🇪 |
66 | 5010103 | 1 | {J&B} | Diageo PLC | GB | 🇬🇧 |
67 | 75010080 | 1 | {CHOCO KRISPIS } | KELLOGG COMPANY MEXICO, S. DE R.L.DE C.V. KELLOGG | MX | 🇲🇽 |
68 | 75010152 | 1 | {PELIK} | PELIKAN MEXICO, S.A. DE C.V. PELIKAN | MX | 🇲🇽 |
69 | 75010329 | 1 | {GLADE} | S.C. JOHNSON AND SON S.A. DE C.V. S.C. JOHNSON... | MX | 🇲🇽 |
70 | 4006584 | 1 | {L.B.L} | OSRAM GmbH CRM&S MDS P-W | DE | 🇩🇪 |
71 | 75010641 | 1 | {CORONA} | CERVECERIA MODELO, S. DE R.L. DE C.V. CERVECER... | MX | 🇲🇽 |
72 | 4005800 | 1 | {NIVEA} | Beiersdorf AG | DE | 🇩🇪 |
73 | 303371 | 1 | {NESCAFE} | NESTLE FRANCE SAS | FR | 🇫🇷 |
74 | 0742832 | 1 | {AOC} | Tufftek | US | 🇺🇸 |
76 | 0681326 | 1 | {SIN MARCA} | Jazwares | US | 🇺🇸 |
77 | 7590002 | 1 | {ALWAYS} | PROCTER & GAMBLE DE VENEZUELA, S.C.A. | VE | 🇻🇪 |
El notebook completo está disponible acá: https://gist.github.com/jazzido/35990ebf8c236d3df953eb1f0af9e39c