データサイエンス100本ノックをAlteryxで。74日目(解答)

100本ノック

このページは解答編です。

↓ネ

↓タ

↓バ

↓レ

↓防

↓止

答えと解説

設問はこちらでした。

P-074: レシート明細データ(receipt.csv)の売上日(sales_ymd)に対し、当該週の月曜日からの経過日数を計算し、売上日、直前の月曜日付とともに10件表示せよ(sales_ymdは数値でデータを保持している点に注意)。

※当該週の月曜日からの経過日数を格納するフィールドの名称は「elapsed_days」とすること
※月曜日付を格納するフィールドの名称を「monday」とすること

解答ワークフローは以下のようになります。

日付を扱う問題ですが、月曜日からの経過日数の計算などあって少々知識や工夫が問われる問題です。

Alteryxの持つ曜日関連の機能

Alteryxの持つ週についての機能は以下のとおりです。

  1. 日時型/日付型のデータから曜日情報を取得
  2. 日曜/月曜からの経過日数を取得

1.日時型/日付型のデータから曜日情報を取得

これは、日時ツールもしくはフォーミュラのDateTimeFormatで行います。

日時型・日付型のデータからテキストに変換する際のバリエーションの一つでしかないのですが、一度使ってないとなかなかどういうものに変換可能なのか、まで把握するのも数が多くて大変なので、ご存知ない方も多くいらっしゃるかと思います。

例えば、日時ツールの場合は以下のように「%a」などの形式で曜日情報を得ることが可能です。

同様に、DateTimeFormat関数も「%a」などを使って曜日情報を取ることが可能です。

このカスタム形式ですが、日時ツールはDateTimeFormat関数用の書式も使うことができるのですが、逆は使えないということで、若干混乱のもととなっています。対応表を以下の通り記載しておきます。

カスタム形式内容対象
dy省略形の曜日名日時ツール
day完全な名前の曜日名月曜日日時ツール
EEEE完全な名前の曜日名月曜日日時ツール
%a省略形の曜日名日時ツール、DateTimeFormat関数
%A完全な名前の曜日名月曜日日時ツール、DateTimeFormat関数

この例は、言語設定を日本語にした場合のもので、英語の場合は例えば月曜日は省略形が「Mon」、完全な名前は「Monday」という感じになります。

2.日曜/月曜からの経過日数を取得

週の何日目にあたるのか、というのを出力する方法も用意されています。もっとも、上の方法で曜日がわかればその週の何日目なのか、ということを特定することは簡単です。ただ、直接的に求められるのであればそれに越したことはありません。

これも1と同様に日時ツール、フォーミュラツールで求めることができます。日時ツールの場合は以下のようになります。

フォーミュラツールの場合は以下のような形になります。

カスタム形式内容対象
%u月曜日を1として、月曜日から離れている日数(月:1、火:2、水:3、木:4、金:5、土:6、日:7)日時ツール、DateTimeFormat関数

%で始まるカスタム形式は本来DateTime関数用のものなのですが、日時ツールでも利用可能です。

それでは、それぞれの方法を考慮したワークフローを作っていきたいと思います。

解答その1

まず、%uを使って直接月曜日からの経過日数を求める方法でいきましょう。

最初に、セレクトツールで不要な項目を削除し、さらに日時ツールでsales_ymdを変換していきたいので数値型かた文字列型に変更します。今回はsales_ymdのみあればいいのでその他はすべてチェックを外しています。

次に、日時ツールで日時型データに変換していきましょう。変換するフォーマットは文字列型のデータなので、「文字列を日付/時刻形式に変換する」を選択します。対象のフィールドは「sales_ymd」とし、新しい列名としては「sales_ymd_Date」を選択します。入力された文字列フィールドに一致する形式を選択は「yyyyMMdd」です。

これで、「sales_ymd_Date」フィールドに日付型のデータが得られます。

次に、フォーミュラツールでelapsed_daysとmondayを計算していきましょう。

まず、月曜日からの経過日数(elapsed_days)ですが、「sales_ymd_Date」を%uのカスタム書式で得ることで月曜日を1とした各曜日の経過日数が取得できます。しかし、今回の問題の「elapsed_days」は月曜日を0としますので、-1する必要があります(月曜日からの経過日数なので、月曜日が0となります)。ですので、以下のような計算式となります。

ToNumber(DateTimeFormat([sales_ymd_Date],"%u","日本語"))-1

注意ポイントは、DateTimeFormat関数の戻り値は文字列型であることです。そのため、計算するには一度ToNumer関数で数値型に変換する必要があります。

最終的な設定は以下のようになります。数値としては0~9までの数値しか取らないためByte型で十分です。

次に、「monday」を取得したいと思います。これは、売上日(sales_ymd)の週の月曜日を求めようとしています。このためには、単純に売上日(sales_ymd)から月曜日からの経過日数(elapsed_days)を引けば良いだけです。つまり、DateTimeAdd関数を使って以下のような計算式で求めることが可能です。

DateTimeAdd([sales_ymd_Date],-[elapsed_days],"days")

最終的なフォーミュラツールの設定は、上のelapsed_daysも含めて以下のような設定となります。

ここまで行けば、あとは不要項目削除、リネームを経て、サンプリングツールなどで先頭から10レコード取得すれば完了です。

実際のワークフローは以下のようになります。

フォーミュラツール1つで実現する

実は、上の方法は、フォーミュラツール1つで達成することが可能です。ただし、必要なフィールドが複数あるため、計算式としては3つに分かれます。

「sales_ymd_Date」フィールド:Date型

DateTimeParse(ToString([sales_ymd]),"%Y%m%d","日本語")

「elapsed_days」フィールド:Byte型

ToNumber(DateTimeFormat([sales_ymd_Date],"%u","日本語"))-1

「monday」フィールド:Date型

DateTimeAdd([sales_ymd_Date],-[elapsed_days],"days")

上の計算式を組み込んだフォーミュラツールの設定は以下の通りとなります。

実際のワークフローは以下のようになります。

検索置換ツールを使った方法

最後に、検索置換ツールを使った方法をご紹介します。

まず、セレクトツールで不要な項目を削除し、sales_ymdは文字列型に戻しておきます。

次に、日時ツールを使い、sales_ymdを日付型に変換します(ここまでは最初の方法と同じです)。

その後、さらに日時ツールで曜日名を取得します。新しい列名は「WeekDay」とします。また、これにはカスタム設定として「%a」を指定します。

さて、これとは別に、テキスト入力ツールで曜日対応表を作っておきます。月曜日を0とし、火、水、、、に1、2、、、と対応する表です。対応表の日数の部分は「elapsed_days」というフィールドにしておくと、そのまま利用できます。

これを検索置換ツールを使って結合していきます。以下のように接続します。

ポイントは、検索対象のフィールドは「WeekDay」としておきます(日時ツールで作った曜日名が入っているフィールドです)。検索する値は、曜日対応表の曜日名が入っているフィールドを指定します。今回は「曜日」です。置換オプションは、「フィールドをレコードに追加」を選択し、「elapsed_days」のみにチェックを入れます。

あとは、mondayを求めるだけです。フォーミュラツールを使って求めていきます。

月曜日からの経過日数が求め終わっているので単純に引き算でオッケーです。DateTimeAdd関数を使って、[sales_ymd_Date]から[elapsed_days]を引いていきます。

DateTimeAdd([sales_ymd_Date],-[elapsed_days],"days")

最終的なワークフローは以下のようになります。

まとめ

今回は、曜日を扱う問題でした。曜日を扱うのが必要な場面も出てくるので日時ツール、DateTimeFormat関数に曜日関連の機能があることを覚えておいていただければと思います。

解答ワークフローダウンロード

コメント

タイトルとURLをコピーしました