LoginSignup
2
2

More than 3 years have passed since last update.

データサイエンス100本ノック~初心者未満の戦いpart9

Last updated at Posted at 2020-06-29

これはデータサイエンティストの卵がわけもわからないまま100本ノックを行っていく奮闘録である。
完走できるか謎。途中で消えてもQiitaにあげてないだけと思ってください。

100本ノックの記事
100本ノックのガイド

ネタバレも含みますのでやろうとされている方は注意

よそごとやってて遅延

コレは見づらい!この書き方は危険!等ありましたら教えていただきたいです。心にダメージを負いながら糧とさせていただきます。

この解き方は間違っている!この解釈の仕方は違う!等もありましたらコメントください。

今回は45~51まで。
[前回]41~44
[目次付き初回]

45本目

ここから日付型-文字型-数字型の変換を行う問題が増えていきます
実はよそごとやっていた時に少し日付型をいじることをやっていました。
よかった。脱線も無駄ではなかった。

今回ラストに同一サイトであっても欲しい情報→参考にしたページをまとめておきます。ページが飛びすぎててホントにわからん。

P-045: 顧客データフレーム(df_customer)の生年月日(birth_day)は日付型(Date)でデータを保有している。これをYYYYMMDD形式の文字列に変換し、顧客ID(customer_id)とともに抽出せよ。データは10件を抽出すれば良い。

mine45.py
df=df_customer.copy()
df['birth_day']=pd.to_datetime(df['birth_day']).dt.strftime('%Y%m%d')
df[['customer_id','birth_day']].head(10)

'''模範解答'''
pd.concat([df_customer['customer_id'],
           pd.to_datetime(df_customer['birth_day']).dt.strftime('%Y%m%d')],
          axis = 1).head(10)

問題やっている途中でバグったので.copy()を追加。deepcopyしなきゃいけないようならまた変更します。

今回は.dt.strftime()を使用(参考)。
C言語でprintfを多用していた身としてはフォーマット指定は結構好き。

ただ、何故かdf['birth_day']に直接.dt.strftimeをつなぐとエラーします。
なのでpd.to_datetime()で明示してあげると(?)動きます

typeCheck.py
type(df['birth_day'])
type(pd.to_datetime(df['birth_day']))

どっちも

pandas.core.series.Series

なんですがねぇ

46本目

P-046: 顧客データフレーム(df_customer)の申し込み日(application_date)はYYYYMMD形式の文字列型でデータを保有している。これを日付型(dateやdatetime)に変換し、顧客ID(customer_id)とともに抽出せよ。データは10件を抽出すれば良い。

mine46.py
df=df_customer.copy()
df['application_date']=pd.to_datetime(df['application_date'])
df[['customer_id','application_date']].head()
#df['application_date'].describe
#df['application_date'].apply(lambda x:x.year)

'''模範解答'''
pd.concat([df_customer['customer_id'],pd.to_datetime(df_customer['application_date'])], axis=1).head(10)

文字列型→日付型への変換 https://note.nkmk.me/python-pandas-datetime-timestamp/
途中で上手く変換できてるか試しています。

.applylambdaを使った要素の取り出しはこちら

47本目

P-047: レシート明細データフレーム(df_receipt)の売上日(sales_ymd)はYYYYMMDD形式の数値型でデータを保有している。これを日付型(dateやdatetime)に変換し、レシート番号(receipt_no)、レシートサブ番号(receipt_sub_no)とともに抽出せよ。データは10件を抽出すれば良い。

mine47.py
df=df_receipt.copy()
df['sales_ymd']=pd.to_datetime(df['sales_ymd'].astype(str))
df[['receipt_no','receipt_sub_no','sales_ymd']].head(10)

'''模範解答'''
pd.concat([df_receipt[['receipt_no', 'receipt_sub_no']],
           pd.to_datetime(df_receipt['sales_ymd'].astype('str'))],axis=1).head(10)

数字→文字→日付型と変換してます。数字→文字列への型変換

48本目

この問題、一か所だけ調べても分からない部分ありました。

P-048: レシート明細データフレーム(df_receipt)の売上エポック秒(sales_epoch)は数値型のUNIX秒でデータを保有している。これを日付型(dateやdatetime)に変換し、レシート番号(receipt_no)、レシートサブ番号(receipt_sub_no)とともに抽出せよ。データは10件を抽出すれば良い。

mine48.py
df=df_receipt.copy()
df['sales_epoch']=pd.to_datetime(df['sales_epoch'],unit='s')
df[['receipt_no','receipt_sub_no','sales_epoch']].head(10)

'''模範解答'''
pd.concat([df_receipt[['receipt_no', 'receipt_sub_no']],
           pd.to_datetime(df_receipt['sales_epoch'], unit='s')],axis=1).head(10)

まず、エポック秒とはの記事を読み、最初「これ、intをそのまま時間に直すといけるんじゃね」と安直にやってみましたが出来ず、そのあとも色々試したけれどもギブアップ。答えを見ました。

すると出てきたのはto_datetime('エポック',unit='s')
引数のunitが分からず調べてみたものの、いつものサイトにはなく、仕方ないのでpandasのリファレンスページを開きました。

unitstr, default ‘ns’
The unit of the arg (D,s,ms,us,ns) denote the unit, which is an integer or float number. This will be based off the origin. Example, with unit=’ms’ and origin=’unix’ (the default), this would calculate the number of milliseconds to the unix epoch start.

英語ということもさておき分からん。引数としてD,s,ms,us,nsを受け入れるというのはなんとなくわかるが、sがどのように作用してるかが全く分からん。
どなたか分かる方、参考ページでもいいので、教えてください。。。(もしかして読んでるページがリファレンスじゃない……?)

49-51本目

似たような問題なので一気に行きます

P-049: レシート明細データフレーム(df_receipt)の売上エポック秒(sales_epoch)を日付型(timestamp型)に変換し、"年"だけ取り出してレシート番号(receipt_no)、レシートサブ番号(receipt_sub_no)とともに抽出せよ。データは10件を抽出すれば良い。

P-050: レシート明細データフレーム(df_receipt)の売上エポック秒(sales_epoch)を日付型(timestamp型)に変換し、"月"だけ取り出してレシート番号(receipt_no)、レシートサブ番号(receipt_sub_no)とともに抽出せよ。なお、"月"は0埋め2桁で取り出すこと。データは10件を抽出すれば良い。

P-051: レシート明細データフレーム(df_receipt)の売上エポック秒(sales_epoch)を日付型(timestamp型)に変換し、"日"だけ取り出してレシート番号(receipt_no)、レシートサブ番号(receipt_sub_no)とともに抽出せよ。なお、"日"は0埋め2桁で取り出すこと。データは10件を抽出すれば良い。

mine49.py
df=df_receipt.copy()
df['sales_epoch']=pd.to_datetime(df['sales_epoch'],unit='s')
df['sales_epoch']=df['sales_epoch'].dt.strftime('%Y')

df[['receipt_no','receipt_sub_no','sales_epoch']].head(10)

'''模範解答'''
pd.concat([df_receipt[['receipt_no', 'receipt_sub_no']],
           pd.to_datetime(df_receipt['sales_epoch'], unit='s').dt.strftime('%Y')],axis=1).head(10)

# %Y を %m %d に変えれば月・日が出せる

エポック秒→日付型→文字列型抜き出しで49~51はできる

ただし、50,51の指定に

なお、"月(日)"は0埋め2桁で取り出すこと。

とあるために

'''罠(ドボン)'''
pd.to_datetime(df['sales_epoch'], unit='s').dt.year

と、やると年は問題なく4桁で出るが月・日は0埋めにならない。
(逆に最初%02dとかやったけどやらなくても0埋めになった)

今回はここまで

参考ページ

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2