Wir werden das Python-Problem von [Data Science 100 Knock (Strukturierte Datenverarbeitung)] lösen (https://github.com/The-Japan-DataScientist-Society/100knocks-preprocess). Diese Gruppe von Fragen verwendet Pandas für die Datenverarbeitung in der Modellantwort, aber wir werden sie nach dem Studium mit NumPy verarbeiten.
: arrow_up: Erster Artikel (# 1) : arrow_backward: Vorheriger Artikel (# 5) : arrow_forward: Nächster Artikel (# 7)
Als Studie von NumPy werde ich das Python-Problem von [Data Science 100 Knock (Strukturierte Datenverarbeitung)] lösen (https://github.com/The-Japan-DataScientist-Society/100knocks-preprocess).
Viele Leute, die mit Python datenwissenschaftliche Dinge tun, mögen Pandas-Liebhaber sein, aber tatsächlich können Sie dasselbe mit NumPy tun, ohne ** Pandas ** zu verwenden. Und NumPy ist normalerweise schneller. Als eine Person, die Pandas liebt, bin ich es immer noch nicht gewohnt, NumPy zu betreiben. Daher möchte ich versuchen, einen Abschluss von Pandas zu machen, indem ich diesen "Data Science 100 Knock" mit NumPy betreibe.
Dieses Mal werde ich die 52. bis 62. Frage beantworten. Es scheint das Thema der Datenkategorisierung zu sein. Die Anfangsdaten wurden wie folgt gelesen.
import numpy as np
import pandas as pd
from numpy.lib import recfunctions as rfn
#Für Modellantwort
df_customer = pd.read_csv('data/customer.csv')
df_receipt = pd.read_csv('data/receipt.csv')
#Daten, mit denen wir umgehen
arr_customer = np.genfromtxt(
'data/customer.csv', delimiter=',', encoding='utf-8',
names=True, dtype=None)
arr_receipt = np.genfromtxt(
'data/receipt.csv', delimiter=',', encoding='utf-8',
names=True, dtype=None)
Schließlich eine Funktion zum Ausgeben des Berechnungsergebnisses als strukturiertes Array
def make_array(size, **kwargs):
arr = np.empty(size, dtype=[(colname, subarr.dtype)
for colname, subarr in kwargs.items()])
for colname, subarr in kwargs.items():
arr[colname] = subarr
return arr
P_052
P-052: Gesamtumsatz (Betrag) des Belegdaten-Datenrahmens (df_receipt) für jede Kunden-ID (customer_id) und 0 für 2000 Yen oder weniger und 1 für über 2000 Yen für den Gesamtumsatz. Zeigen Sie dann 10 Artikel zusammen mit der Kunden-ID und dem Gesamtumsatz an. Wenn die Kunden-ID jedoch mit "Z" beginnt, handelt es sich um ein Nichtmitglied. Schließen Sie sie daher von der Berechnung aus.
Verkäufe nach Kunden werden nach dem üblichen np.unique ()
+ np.bincount ()
berechnet. "0 für weniger als 2000 Yen und 1 für mehr als 2000" konvertiert einfach das boolesche Array im Vergleich zu 2000 in einen numerischen Wert (False entspricht 0 und True entspricht 1).
In[052]
is_member = arr_receipt['customer_id'].astype('<U1') != 'Z'
unq_id, inv_id = np.unique(arr_receipt['customer_id'][is_member],
return_inverse=True)
amount_arr = np.bincount(inv_id, arr_receipt['amount'][is_member])
make_array(unq_id.size,
customer_id=unq_id,
amount=amount_arr,
sales_flg=(amount_arr > 2000).view(np.int8))[:10]
Out[052]
array([('CS001113000004', 1298., 0), ('CS001114000005', 626., 0),
('CS001115000010', 3044., 1), ('CS001205000004', 1988., 0),
('CS001205000006', 3337., 1), ('CS001211000025', 456., 0),
('CS001212000027', 448., 0), ('CS001212000031', 296., 0),
('CS001212000046', 228., 0), ('CS001212000070', 456., 0)],
dtype=[('customer_id', '<U14'), ('amount', '<f8'), ('sales_flg', 'i1')])
Time[052]
#Musterantwort
%%timeit
df_sales_amount = df_receipt.query('not customer_id.str.startswith("Z")', engine='python')
df_sales_amount = df_sales_amount[['customer_id', 'amount']].groupby('customer_id').sum().reset_index()
df_sales_amount['sales_flg'] = df_sales_amount['amount'].apply(lambda x: 1 if x > 2000 else 0)
df_sales_amount.head(10)
# 72.9 ms ± 1.67 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
#Verbesserung
%%timeit
df_sales_amount = df_receipt.loc[~df_receipt['customer_id'].str.startswith('Z'), ['customer_id', 'amount']].groupby('customer_id', as_index=False).sum()
df_sales_amount['sales_flg'] = (df_sales_amount['amount'] > 2000).astype(int)
df_sales_amount.head(10)
# 63.5 ms ± 226 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
#NumPy (siehe Code oben)
# 33.8 ms ± 252 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
P_053
P-053: Für die postal_cd des Kundendatenrahmens (df_customer) binärisieren Sie Tokio (die ersten 3 Ziffern sind 100 bis 209) auf 1 und die anderen auf 0. Kombinieren Sie es außerdem mit dem Datenrahmen für die Belegabrechnung (df_receipt) und zählen Sie für jeden der beiden erstellten Werte die Anzahl der Kunden, die über den gesamten Zeitraum einen Einkaufsdatensatz haben.
Verwenden Sie zunächst np.in1d ()
, um nur Kunden mit einer Kaufhistorie zu extrahieren. Konvertieren Sie anschließend die ersten 3 Ziffern der Postleitzahl in einen numerischen Wert. Sie können .astype ('<U3'). Astype (int)
verwenden, aber hier verwenden wir np.frombuffer ()
zum Konvertieren, ohne .astype ()
([P_011) zu durchlaufen. ](Siehe https://qiita.com/nkay/items/65a77b97ae9b7331b39c#p_011).
In[053]
isin_rec = np.in1d(arr_customer['customer_id'], arr_receipt['customer_id'])
post_int_arr = ((np.frombuffer(
arr_customer['postal_cd'][isin_rec].tobytes(), dtype=np.int32)
- 48).reshape(-1, 8)[:, :3]*np.array([100, 10, 1])).sum(1)
postal_flg = ((101 <= post_int_arr) & (post_int_arr <= 209))
make_array(2, postal_flg=np.arange(2), count=np.bincount(postal_flg))
Out[053]
array([(0, 3906), (1, 4400)],
dtype=[('postal_flg', '<i4'), ('count', '<i8')])
Time[053]
#Musterantwort
%%timeit
df_tmp = df_customer[['customer_id', 'postal_cd']].copy()
df_tmp['postal_flg'] = df_tmp['postal_cd'].apply(lambda x: 1 if 100 <= int(x[0:3]) <= 209 else 0)
pd.merge(df_tmp, df_receipt, how='inner', on='customer_id').groupby('postal_flg').agg({'customer_id':'nunique'})
# 109 ms ± 4.89 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
#NumPy (siehe Code oben)
# 50.2 ms ± 349 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
P_054
P-054: Die Adresse des Kundendaten-Datenrahmens (df_customer) stammt aus der Präfektur Saitama, der Präfektur Chiba, der Metropolregion Tokio und der Präfektur Kanagawa. Erstellen Sie für jede Präfektur einen Codewert und extrahieren Sie ihn zusammen mit der Kunden-ID und der Adresse. Die Werte sollten 11 für die Präfektur Saitama, 12 für die Präfektur Chiba, 13 für Tokio und 14 für die Präfektur Kanagawa sein. Sie können 10 Ergebnisse anzeigen.
Sehen Sie sich den ersten Buchstaben der Adressspalte an und ersetzen Sie ihn durch eine beliebige Nummer (siehe [P_036](siehe https://qiita.com/nkay/items/a77fcb2dd3810d1f20c3#p_036)).
In[054]
caps = np.array(['Sai', 'tausend', 'Osten', 'Gott'], dtype='<U1')
sorter_index = caps.argsort()
idx = np.searchsorted(caps, arr_customer['address'].astype('<U1'),
sorter=sorter_index)
address_code = np.array([11, 12, 13, 14])[sorter_index[idx]]
make_array(arr_customer.size,
customer_id=arr_customer['customer_id'],
address=arr_customer['address'],
address_code=address_code)[:10]
Out[054]
array([('CS021313000114', 'Awakubo, Isehara City, Präfektur Kanagawa**********', 14),
('CS037613000071', 'Minamisago, Koto-ku, Tokio**********', 13),
('CS031415000172', 'Yoyogi, Shibuya-ku, Tokio**********', 13),
('CS028811000001', 'Izumi-cho, Izumi-ku, Yokohama-shi, Kanagawa**********', 14),
('CS001215000145', 'Nakarokugo, Ota-ku, Tokio**********', 13),
('CS020401000016', 'Wakagi, Itabashi-ku, Tokio**********', 13),
('CS015414000103', 'Kitasa, Koto-ku, Tokio**********', 13),
('CS029403000008', 'Stadt Urayasu, Präfektur Chiba**********', 12),
('CS015804000004', 'Kitasa, Koto-ku, Tokio**********', 13),
('CS033513000180', 'Zenbe-cho, Asahi-ku, Yokohama-shi, Kanagawa**********', 14)],
dtype=[('customer_id', '<U14'), ('address', '<U26'), ('address_code', '<i4')])
Time[054]
#Musterantwort
pd.concat([df_customer[['customer_id', 'address']],
df_customer['address'].str[0:3].map({'Saitama': '11', 'Präfektur Chiba': '12', 'Tokio': '13', 'Kanagawa': '14'})],
axis=1).head(10)
# 16.2 ms ± 963 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)
#NumPy (siehe Code oben)
# 4.52 ms ± 176 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
P_055
P-055: Summieren Sie den Verkaufsbetrag (Betrag) des Belegdetail-Datenrahmens (df_receipt) für jede Kunden-ID (customer_id) und ermitteln Sie den Quadranten des Gesamtbetrags. Erstellen Sie dann einen Kategoriewert für den Gesamtumsatz für jeden Kunden basierend auf den folgenden Kriterien und zeigen Sie sowohl die Kunden-ID als auch den Verkaufsbetrag an. Kategoriewerte sind 1 bis 4 in der Reihenfolge von oben. Sie können 10 Ergebnisse anzeigen.
- Minimalwert oder mehr und weniger als der erste Quadrant
- Vom ersten Quadranten auf weniger als den zweiten Quadranten
- Vom zweiten Quadranten auf weniger als den dritten Quadranten
- Drittes Quartal und höher
Verkäufe nach Kunden werden nach dem üblichen np.unique ()
+ np.bincount ()
berechnet. Verwenden Sie als Nächstes np.quantile ()
, um den Quadranten zu finden. Vergleichen Sie abschließend die Verkäufe nach Kunden mit dem Quadrantenwert, um herauszufinden, zu welcher Gruppe Sie gehören (Sie können auch np.searchsorted ()
verwenden).
In[055]
unq_id, inv_id = np.unique(arr_receipt['customer_id'],
return_inverse=True)
amount_arr = np.bincount(inv_id, arr_receipt['amount'])
quantiles = np.quantile(amount_arr, np.arange(1, 4)/4)
pct_group = (quantiles[:, None] <= amount_arr).sum(0) + 1
make_array(unq_id.size,
customer_id=unq_id, amount=amount_arr, pct_group=pct_group)[:10]
Out[055]
array([('CS001113000004', 1298., 2), ('CS001114000005', 626., 2),
('CS001115000010', 3044., 3), ('CS001205000004', 1988., 3),
('CS001205000006', 3337., 3), ('CS001211000025', 456., 1),
('CS001212000027', 448., 1), ('CS001212000031', 296., 1),
('CS001212000046', 228., 1), ('CS001212000070', 456., 1)],
dtype=[('customer_id', '<U14'), ('amount', '<f8'), ('pct_group', '<i8')])
P_056
P-056: Berechnen Sie das Alter in Schritten von 10 Jahren basierend auf dem Alter des Kundendatenrahmens (df_customer) und extrahieren Sie es zusammen mit der Kunden-ID (Kunden-ID) und dem Geburtsdatum (Geburtsdatum). Alle Personen über 60 sollten jedoch über 60 Jahre alt sein. Der Kategoriename, der das Alter angibt, ist beliebig. Die ersten 10 Elemente sollten angezeigt werden.
In[056]
age = arr_customer['age']//10*10
age[age > 60] = 60
arr_customer_era = make_array(arr_customer.size,
customer_id=arr_customer['customer_id'],
birth_day=arr_customer['birth_day'],
age=age)
arr_customer_era[:10]
Sie können auch np.clip ()
oder np.where ()
verwenden.
Out[056]
array([('CS021313000114', '1981-04-29', 30),
('CS037613000071', '1952-04-01', 60),
('CS031415000172', '1976-10-04', 40),
('CS028811000001', '1933-03-27', 60),
('CS001215000145', '1995-03-29', 20),
('CS020401000016', '1974-09-15', 40),
('CS015414000103', '1977-08-09', 40),
('CS029403000008', '1973-08-17', 40),
('CS015804000004', '1931-05-02', 60),
('CS033513000180', '1962-07-11', 50)],
dtype=[('customer_id', '<U14'), ('birth_day', '<U10'), ('age', '<i4')])
P_057
P-057: Kombinieren Sie das Extraktionsergebnis der vorherigen Frage und des Geschlechts (Geschlecht) und erstellen Sie neue Kategoriedaten, die die Kombination von Geschlecht und Alter darstellen. Der Wert der Kategorie, die die Kombination darstellt, ist beliebig. Die ersten 10 Elemente sollten angezeigt werden.
In[057]
arr_customer_era = make_array(arr_customer.size,
customer_id=arr_customer['customer_id'],
birth_day=arr_customer['birth_day'],
age=age,
era_gender=arr_customer['gender_cd']*100+age)
arr_customer_era[:10]
Out[057]
array([('CS021313000114', '1981-04-29', 30, 130),
('CS037613000071', '1952-04-01', 60, 960),
('CS031415000172', '1976-10-04', 40, 140),
('CS028811000001', '1933-03-27', 60, 160),
('CS001215000145', '1995-03-29', 20, 120),
('CS020401000016', '1974-09-15', 40, 40),
('CS015414000103', '1977-08-09', 40, 140),
('CS029403000008', '1973-08-17', 40, 40),
('CS015804000004', '1931-05-02', 60, 60),
('CS033513000180', '1962-07-11', 50, 150)],
dtype=[('customer_id', '<U14'), ('birth_day', '<U10'), ('age', '<i4'), ('era_gender', '<i4')])
P_058
P-058: Machen Sie den Gender-Code (gender_cd) des Kundendatenrahmens (df_customer) zu einer Dummy-Variablen und extrahieren Sie ihn zusammen mit der Kunden-ID (customer_id). Sie können 10 Ergebnisse anzeigen.
Broca.
In[058]
dummies = (arr_customer['gender_cd']
== np.array([[0], [1], [9]])).view(np.int8)
make_array(arr_customer.size,
customer_id=arr_customer['customer_id'],
gender_cd_0=dummies[0],
gender_cd_1=dummies[1],
gender_cd_9=dummies[2])[:10]
Out[058]
gender_cd = np.ascontiguousarray(arr_customer['gender_cd'])...
array([('CS021313000114', 0, 1, 0), ('CS037613000071', 0, 0, 1),
('CS031415000172', 0, 1, 0), ('CS028811000001', 0, 1, 0),
('CS001215000145', 0, 1, 0), ('CS020401000016', 1, 0, 0),
('CS015414000103', 0, 1, 0), ('CS029403000008', 1, 0, 0),
('CS015804000004', 1, 0, 0), ('CS033513000180', 0, 1, 0)],
dtype=[('customer_id', '<U14'), ('gender_cd_0', 'i1'), ('gender_cd_1', 'i1'), ('gender_cd_9', 'i1')])
P_059
P-059: Der Gesamtverkaufsbetrag (Betrag) des Belegdaten-Datenrahmens (df_receipt) wird für jede Kunden-ID (customer_id) summiert, und der Gesamtverkaufsbetrag wird auf den Durchschnitt 0 und die Standardabweichung 1 auf die Gesamtkunden-ID und den Verkaufsbetrag standardisiert. Anzeige mit. Die zur Standardisierung verwendete Standardabweichung kann entweder eine unverzerrte Standardabweichung oder eine Stichprobenstandardabweichung sein. Wenn die Kunden-ID jedoch mit "Z" beginnt, handelt es sich um ein Nichtmitglied. Schließen Sie sie daher von der Berechnung aus. Sie können 10 Ergebnisse anzeigen.
Einfach auf die Formel anwenden. Mit scipy.stats.zscore ()
ist das ganz einfach.
In[059]
is_member = arr_receipt['customer_id'].astype('<U1') != 'Z'
unq_id, inv_id = np.unique(arr_receipt['customer_id'][is_member],
return_inverse=True)
amount_arr = np.bincount(inv_id, arr_receipt['amount'][is_member])
amount_mean = amount_arr.mean()
amount_std = np.sqrt(((amount_arr-amount_mean)**2).mean())
amount_ss = (amount_arr - amount_mean) / amount_std
# amount_ss = scipy.stats.zscore(amount_mean)Aber ok
make_array(unq_id.size,
customer_id=unq_id, amount=amount_arr, amount_ss=amount_ss)[:10]
Out[059]
array([('CS001113000004', 1298., -0.45937788),
('CS001114000005', 626., -0.70639037),
('CS001115000010', 3044., 0.18241349),
('CS001205000004', 1988., -0.20574899),
('CS001205000006', 3337., 0.29011387),
('CS001211000025', 456., -0.76887864),
('CS001212000027', 448., -0.77181927),
('CS001212000031', 296., -0.82769114),
('CS001212000046', 228., -0.85268645),
('CS001212000070', 456., -0.76887864)],
dtype=[('customer_id', '<U14'), ('amount', '<f8'), ('amount_ss', '<f8')])
P_060
P-060: Der Verkaufsbetrag (Betrag) des Belegdetail-Datenrahmens (df_receipt) wird für jede Kunden-ID (customer_id) summiert, und der Gesamtverkaufsbetrag wird auf den Mindestwert 0 und den Maximalwert 1 auf die Kunden-ID und den Verkaufsbetrag normiert. Anzeige mit der Summe. Wenn die Kunden-ID jedoch mit "Z" beginnt, handelt es sich um ein Nichtmitglied. Schließen Sie sie daher von der Berechnung aus. Sie können 10 Ergebnisse anzeigen.
Einfach auf die Formel anwenden.
In[060]
is_member = arr_receipt['customer_id'].astype('<U1') != 'Z'
unq_id, inv_id = np.unique(arr_receipt['customer_id'][is_member],
return_inverse=True)
amount_arr = np.bincount(inv_id, arr_receipt['amount'][is_member])
amount_min, amount_max = amount_arr.min(), amount_arr.max()
amount_mm = (amount_arr - amount_min) / (amount_max - amount_min)
make_array(unq_id.size,
customer_id=unq_id, amount=amount_arr, amount_mm=amount_mm)[:10]
Out[060]
array([('CS001113000004', 1298., 0.05335419),
('CS001114000005', 626., 0.02415711),
('CS001115000010', 3044., 0.12921446),
('CS001205000004', 1988., 0.08333333),
('CS001205000006', 3337., 0.14194473),
('CS001211000025', 456., 0.01677094),
('CS001212000027', 448., 0.01642336),
('CS001212000031', 296., 0.00981926),
('CS001212000046', 228., 0.00686479),
('CS001212000070', 456., 0.01677094)],
dtype=[('customer_id', '<U14'), ('amount', '<f8'), ('amount_mm', '<f8')])
P_061
P-061: Der Verkaufsbetrag (Betrag) des Belegdetail-Datenrahmens (df_receipt) wird für jede Kunden-ID (customer_id) summiert, und der Gesamtverkaufsbetrag wird in einen regulären logarithmischen Wert (Basis = 10) umgewandelt, um die Kunden-ID und den Verkaufsbetrag zu summieren. Anzeige mit. Wenn die Kunden-ID jedoch mit "Z" beginnt, handelt es sich um ein Nichtmitglied. Schließen Sie sie daher von der Berechnung aus. Sie können 10 Ergebnisse anzeigen.
In[061]
is_member = arr_receipt['customer_id'].astype('<U1') != 'Z'
unq_id, inv_id = np.unique(arr_receipt['customer_id'][is_member],
return_inverse=True)
amount_arr = np.bincount(inv_id, arr_receipt['amount'][is_member])
make_array(unq_id.size, customer_id=unq_id, amount=amount_arr,
amount_log10=np.log10(amount_arr + 1))[:10]
Out[061]
array([('CS001113000004', 1298., 3.11360915),
('CS001114000005', 626., 2.79726754),
('CS001115000010', 3044., 3.4835873 ),
('CS001205000004', 1988., 3.29863478),
('CS001205000006', 3337., 3.52348633),
('CS001211000025', 456., 2.6599162 ),
('CS001212000027', 448., 2.65224634),
('CS001212000031', 296., 2.47275645),
('CS001212000046', 228., 2.35983548),
('CS001212000070', 456., 2.6599162 )],
dtype=[('customer_id', '<U14'), ('amount', '<f8'), ('amount_log10', '<f8')])
P_062
P-062: Der Verkaufsbetrag (Betrag) des Belegdetail-Datenrahmens (df_receipt) wird für jede Kunden-ID (customer_id) summiert, und der Gesamtverkaufsbetrag wird in einen natürlichen logarithmischen Wert (Basis = e) umgewandelt, um die Kunden-ID und den Verkaufsbetrag zu summieren Anzeige mit. Wenn die Kunden-ID jedoch mit "Z" beginnt, handelt es sich um ein Nichtmitglied. Schließen Sie sie daher von der Berechnung aus. Sie können 10 Ergebnisse anzeigen.
In[062]
is_member = arr_receipt['customer_id'].astype('<U1') != 'Z'
unq_id, inv_id = np.unique(arr_receipt['customer_id'][is_member],
return_inverse=True)
amount_arr = np.bincount(inv_id, arr_receipt['amount'][is_member])
make_array(unq_id.size, customer_id=unq_id, amount=amount_arr,
amount_log10=np.log1p(amount_arr))[:10]
Out[062]
array([('CS001113000004', 1298., 7.16935002),
('CS001114000005', 626., 6.44094654),
('CS001115000010', 3044., 8.02125618),
('CS001205000004', 1988., 7.59538728),
('CS001205000006', 3337., 8.1131271 ),
('CS001211000025', 456., 6.12468339),
('CS001212000027', 448., 6.10702289),
('CS001212000031', 296., 5.69373214),
('CS001212000046', 228., 5.433722 ),
('CS001212000070', 456., 6.12468339)],
dtype=[('customer_id', '<U14'), ('amount', '<f8'), ('amount_log10', '<f8')])
Recommended Posts