データサイエンス100本ノック 61~70

データサイエンス100本ノック 61~70#

import polars as pl
from helper.polars import load_100knocks_data
pl.Config.set_fmt_str_lengths(100)
df_customer, df_category, df_product, df_receipt, df_store, df_geocode = load_100knocks_data()

P-061#

レシート明細データ(df_receipt)の売上金額(amount)を顧客ID(customer_id)ごとに合計し、売上金額合計を常用対数化(底10)して顧客ID、売上金額合計とともに10件表示せよ。ただし、顧客IDが”Z”から始まるのものは非会員を表すため、除外して計算すること。

(
df_receipt
.group_by('customer_id')
.agg(
    pl.col.amount.sum().alias('sum_amount'),
    (pl.col.amount.sum() + 0.5).log10().alias('log_amount')
)
.head()
)
shape: (5, 3)
customer_idsum_amountlog_amount
stri64f64
"CS025515000057"80133.903822
"CS013414000081"53433.727826
"CS010315000024"2022.306425
"CS001515000463"7842.894593
"CS007512000029"3282.516535

P-062#

レシート明細データ(df_receipt)の売上金額(amount)を顧客ID(customer_id)ごとに合計し、売上金額合計を自然対数化(底e)して顧客ID、売上金額合計とともに10件表示せよ。ただし、顧客IDが”Z”から始まるのものは非会員を表すため、除外して計算すること。

(
df_receipt
.group_by('customer_id')
.agg(
    pl.col.amount.sum().alias('sum_amount'),
    (pl.col.amount.sum() + 0.5).log().alias('log_amount')
)
.head()
)
shape: (5, 3)
customer_idsum_amountlog_amount
stri64f64
"CS037615000085"2025.31074
"CS030212000045"2085.339939
"CS028415000215"40628.309554
"CS005214000025"40288.301149
"CS034513000213"29087.975393

P-063#

商品データ(df_product)の単価(unit_price)と原価(unit_cost)から各商品の利益額を算出し、結果を10件表示せよ。

(
df_product
.select(
    pl.col.product_cd,
    pl.col.unit_price,
    pl.col.unit_cost,
    (pl.col.unit_price - pl.col.unit_cost).alias('unit_profit')
)
.head()
)
shape: (5, 4)
product_cdunit_priceunit_costunit_profit
stri64i64i64
"P040101001"19814949
"P040101002"21816454
"P040101003"23017357
"P040101004"24818662
"P040101005"26820167

P-064#

商品データ(df_product)の単価(unit_price)と原価(unit_cost)から、各商品の利益率の全体平均を算出せよ。ただし、単価と原価には欠損が生じていることに注意せよ。

(
df_product
.select(
    ((pl.col.unit_price - pl.col.unit_cost) / pl.col.unit_price).mean()
)
.item()
)
0.24911389885177007

P-065#

商品データ(df_product)の各商品について、利益率が30%となる新たな単価を求めよ。ただし、1円未満は切り捨てること。そして結果を10件表示させ、利益率がおよそ30%付近であることを確認せよ。ただし、単価(unit_price)と原価(unit_cost)には欠損が生じていることに注意せよ。

(
df_product
.select(
    pl.col.product_cd,
    pl.col.unit_price,
    pl.col.unit_cost,
    (pl.col.unit_cost / 0.7).floor().cast(pl.Int32).alias('new_price')
)
.with_columns(
    new_profit_rate=(pl.col.new_price - pl.col.unit_cost) / pl.col.new_price
)
.head(10)
)
shape: (10, 5)
product_cdunit_priceunit_costnew_pricenew_profit_rate
stri64i64i32f64
"P040101001"1981492120.29717
"P040101002"2181642340.299145
"P040101003"2301732470.299595
"P040101004"2481862650.298113
"P040101005"2682012870.299652
"P040101006"2982243200.3
"P040101007"3382543620.298343
"P040101008"4203154500.3
"P040101009"4983745340.299625
"P040101010"5804356210.299517

P-066#

商品データ(df_product)の各商品について、利益率が30%となる新たな単価を求めよ。今回は、1円未満を丸めること(四捨五入または偶数への丸めで良い)。そして結果を10件表示させ、利益率がおよそ30%付近であることを確認せよ。ただし、単価(unit_price)と原価(unit_cost)には欠損が生じていることに注意せよ。

(
df_product
.select(
    pl.col.product_cd,
    pl.col.unit_price,
    pl.col.unit_cost,
    (pl.col.unit_cost / 0.7)
        .round()
        .cast(pl.Int32)
        .alias('new_price')
)
.with_columns(
    new_profit_rate=(pl.col.new_price - pl.col.unit_cost) / pl.col.new_price
)
.head(10)
)
shape: (10, 5)
product_cdunit_priceunit_costnew_pricenew_profit_rate
stri64i64i32f64
"P040101001"1981492130.300469
"P040101002"2181642340.299145
"P040101003"2301732470.299595
"P040101004"2481862660.300752
"P040101005"2682012870.299652
"P040101006"2982243200.3
"P040101007"3382543630.300275
"P040101008"4203154500.3
"P040101009"4983745340.299625
"P040101010"5804356210.299517

P-067#

商品データ(df_product)の各商品について、利益率が30%となる新たな単価を求めよ。今回は、1円未満を切り上げること。そして結果を10件表示させ、利益率がおよそ30%付近であることを確認せよ。ただし、単価(unit_price)と原価(unit_cost)には欠損が生じていることに注意せよ。

(
df_product
.select(
    pl.col.product_cd,
    pl.col.unit_price,
    pl.col.unit_cost,
    (pl.col.unit_cost / 0.7)
        .ceil()
        .cast(pl.Int32)
        .alias('new_price')
)
.with_columns(
    new_profit_rate=(pl.col.new_price - pl.col.unit_cost) / pl.col.new_price
)
.head(10)
)
shape: (10, 5)
product_cdunit_priceunit_costnew_pricenew_profit_rate
stri64i64i32f64
"P040101001"1981492130.300469
"P040101002"2181642350.302128
"P040101003"2301732480.302419
"P040101004"2481862660.300752
"P040101005"2682012880.302083
"P040101006"2982243200.3
"P040101007"3382543630.300275
"P040101008"4203154500.3
"P040101009"4983745350.300935
"P040101010"5804356220.300643

P-068#

商品データ(df_product)の各商品について、消費税率10%の税込み金額を求めよ。1円未満の端数は切り捨てとし、結果を10件表示せよ。ただし、単価(unit_price)には欠損が生じていることに注意せよ。

(
df_product
.select(
    pl.col.product_cd,
    pl.col.unit_price,
    (pl.col.unit_price * 1.1)
        .floor()
        .cast(pl.Int32)
        .alias('tex_price')
)
.head(10)
)
shape: (10, 3)
product_cdunit_pricetex_price
stri64i32
"P040101001"198217
"P040101002"218239
"P040101003"230253
"P040101004"248272
"P040101005"268294
"P040101006"298327
"P040101007"338371
"P040101008"420462
"P040101009"498547
"P040101010"580638

P-069#

レシート明細データ(df_receipt)と商品データ(df_product)を結合し、顧客毎に全商品の売上金額合計と、カテゴリ大区分コード(category_major_cd)が”07”(瓶詰缶詰)の売上金額合計を計算の上、両者の比率を求めよ。抽出対象はカテゴリ大区分コード”07”(瓶詰缶詰)の売上実績がある顧客のみとし、結果を10件表示せよ。

(
df_receipt
.join(df_product, on='product_cd', how='left')
.group_by('customer_id', maintain_order=True)
.agg(
    sum_all=pl.col.amount.sum(),
    sum_07=pl.col.amount
        .filter(pl.col.category_major_cd == '07')
        .sum()
)
.with_columns(
    sales_rate=pl.col.sum_07 / pl.col.sum_all
)
.head(10)
)
shape: (10, 4)
customer_idsum_allsum_07sales_rate
stri64i64f64
"CS006214000001"736447130.640005
"CS008415000097"189513370.705541
"CS028414000014"622237010.594825
"ZZ000000000000"1239500369430090.560146
"CS025415000050"573635360.616457
"CS003515000195"541245810.846452
"CS024514000042"53300.0
"CS040415000178"614948020.78094
"CS027514000015"278814750.529053
"CS025415000134"490234300.699714

P-070#

レシート明細データ(df_receipt)の売上日(sales_ymd)に対し、顧客データ(df_customer)の会員申込日(application_date)からの経過日数を計算し、顧客ID(customer_id)、売上日、会員申込日とともに10件表示せよ(sales_ymdは数値、application_dateは文字列でデータを保持している点に注意)。

(
df_receipt
.select('customer_id', 'sales_ymd')
.unique()
.join(df_customer, on='customer_id')
.select(
    pl.col.customer_id,
    pl.col.sales_ymd.cast(str).str.strptime(pl.Date, '%Y%m%d'),
    pl.col.application_date.cast(str).str.strptime(pl.Date, '%Y%m%d')
)
.with_columns(
    elapsed_days=(pl.col.sales_ymd - pl.col.application_date).dt.total_days()
)
.head()
)
shape: (5, 4)
customer_idsales_ymdapplication_dateelapsed_days
strdatedatei64
"CS020414000112"2019-02-042015-04-271379
"CS021515000011"2017-03-122015-06-29622
"CS014514000085"2017-01-212015-06-06595
"CS014415000088"2017-10-092015-12-21658
"CS008514000055"2018-12-032015-02-121390