【R言語】uniteを使った列の結合

unite関数は、データフレームの列を結合するための関数で、複数の列を結合して新しい列を作成することができます。

unite関数は、以下のような構文を持ちます。

unite(data, col, ..., sep = "_", remove = TRUE)
  • data : データフレーム
  • col : 新しい列名
  • ... : 結合する列名
  • sep : 区切り文字
    • デフォルトでは「_」
  • remove : 結合した列を削除するかどうか
    • デフォルトでは削除する

パイプ演算子を用いたやり方では下記のように使います。

df %>%
    unite(col, ..., sep = "_", remove = TRUE)

第一引数がdata(data.frame)ではなくcol(新しい列名)になっています。

こちらのデータのうち和暦・給付年度・被災学校種の3列を用いて使用例を書いていきたいと思います。

先頭5行は下記のとおり

和暦 給付年度 被災学校種
平成 17
平成 17
平成 17
平成 17
平成 17

環境

ライブラリの読み込み

library(tidyverse)
library(readxl)

データの読み込み

df <- read_excel("shougai_20230201.xlsx") %>% 
      select(和暦, 給付年度, 被災学校種)

このデータフレームに対して、和暦列と 給付年度列を結合して新しい列和暦_ 給付年度を作成する場合は、以下のようにします。

df %>% 
    unite(和暦_給付年度, 和暦, 給付年度) %>%
    head(5)
和暦_給付年度 被災学校種
平成_17
平成_17
平成_17
平成_17
平成_17

このコードでは、dfデータフレームの和暦列と 給付年度列を結合して新しい列和暦_ 給付年度を作成しています。結合に用いた2つの列は削除され新しい列ができています。

区切り文字を指定する

区切り文字はデフォルトではアンダースコア(_)が用いられます。指定したい場合はsepで指定します。
下記のコードでは区切り文字を半角( )を指定しています。

df %>% 
    unite(和暦_給付年度, 和暦, 給付年度, sep = " ") %>%
    head(5)
和暦_給付年度 被災学校種
平成 17
平成 17
平成 17
平成 17
平成 17

区切り文字をなくしたい場合はsep=""とします。

df %>% 
    unite(和暦_給付年度, 和暦, 給付年度, sep="") %>%
    head(5)
和暦_給付年度 被災学校種
平成17
平成17
平成17
平成17
平成17

結合に用いた列を残す

デフォルトでは結合に用いた列は残りません。結合に用いた2つの列を残したい場合は引数のremoveでFALSEを指定します。

df %>% 
    unite(和暦_給付年度, 和暦, 給付年度, remove = FALSE) %>%
    head(5)
和暦_給付年度 和暦 給付年度 被災学校種
平成_17 平成 17
平成_17 平成 17
平成_17 平成 17
平成_17 平成 17
平成_17 平成 17

複数列を結合する

複数列を結合する場合は、結合したい列をカンマで区切って追加していきます。 下記のコードでは、和暦・給付年度・ 被災学校種の3列を用いて和暦給付年度被災学校種という列を作っています。

df %>% 
    unite(和暦_給付年度_被災学校種, 和暦, 給付年度, 被災学校種) %>%
    head(5)
和暦_給付年度_被災学校種
平成_17_小
平成_17_小
平成_17_小
平成_17_小
平成_17_小

SQLのcase whenと同じことをpandas.DataFrameに対して行う

pandas.DataFrameに対してSQLのcase whenと同じことをして、新しい列を作る方法がはいくつかあるようなので、まとめておく。

元データ

import pandas as pd
import numpy as np

df=pd.DataFrame({'fruit':['Strawberry','Apple', 'Peach', 'Banana', 'grapes']})
df
fruit
0 Strawberry
1 Apple
2 Peach
3 Banana
4 grapes

上記が元データで、下記の「果物」という新しい列を加えたdataftameにしたい

fruit 果物
0 Strawberry いちご
1 Apple りんご
2 Peach もも
3 Banana ばなな
4 grapes ぶどう

numpy.where()

numpy.where()を使って新しい列を作成する方法。 個人的には比較的読みやすい書き方と感じる。ただしネストが深くなり、処理速度が遅い。データ量が少ない時は処理速度を気にしなくて良いので、読みやすいnumpy.where()を使うことが多い。

df['果物']=np.where(df['fruit']=='Strawberry', 'いちご',
           np.where(df['fruit']=='Apple', 'りんご',
           np.where(df['fruit']=='Peach', 'もも',
           np.where(df['fruit']=='Banana', 'ばなな',
           np.where(df['fruit']=='grapes', 'ぶどう',
           'その他')))))

if文による関数作ってapply

処理速度が速い。ただし、個人的には読みにくいと感じる。データ量が多くelifの数が少ない場合は、処理速度を優先させたいのでこの方法を使うことが多い。

def func(x):
    if  x=='Strawberry':
        return 'いちご'
    elif x=='Apple':
        return 'りんご'
    elif x=='Peach':
        return 'もも'
    elif x=='Banana':
        return 'ばなな'
    elif x=='grapes':
        return 'ぶどう'    
    else:
        return 'その他'

df['果物'] = df['fruit'].apply(func)

df.loc

処理速度はnumpy.where()よりは早く、if文による関数作ってapplyよりは少し遅い。一緒に仕事をする方が良くdf.locを使うようであればこの方法を使うことが多い。

df.loc[df['fruit'] == 'Strawberry', '果物'] = 'いちご'
df.loc[df['fruit'] == 'Apple', '果物'] = 'りんご'
df.loc[df['fruit'] == 'Peach', '果物'] = 'もも'
df.loc[df['fruit'] == 'Banana', '果物'] = 'ばなな'
df.loc[df['fruit'] == 'grapes', '果物'] = 'ぶどう'

3つの方法を記載したが、それぞれ良さがあり適宜適切な方法を選択したいところ。

【Python】pd.period_range()を使ってyyyy-MM.parquetのファイルを順番に読み込む

下記のようなディレクトリ構成になっているときに、いい感じにファイル名のyyyy-MMを順番に取得して、処理をしたいときはpd.period_range()が便利です。

GA_log
├── 2017-01.parquet
├── 2017-02.parquet
├── 2017-03.parquet
├── 2017-04.parquet
├── 2017-05.parquet
├── 2017-06.parquet
├── 2017-07.parquet
├── 2017-08.parquet
├── 2017-09.parquet
├── 2017-10.parquet
├── 2017-11.parquet
├── 2017-12.parquet
└── 2018-01.parquet

pd.period_range()とは

pd.period_range()は、pandasの関数の1つで、固定頻度のPeriodIndexを返すために使用されます。この関数は、日(カレンダー)をデフォルトの頻度として使用します。期間の開始と終了を指定することができ、期間の長さを指定することもできます。freq引数で'M'を指定することでyyyy-MMを取得することができます。

pd.period_range()の基本的な使いかた

pd.period_range(start, end, periods=None, freq=None, name=None)
  • start:Periodまたは文字列で表される開始日付
  • end:Periodまたは文字列で表される終了日付
  • periods:PeriodIndexオブジェクトに含まれる期間の数。省略すると、startと- endの日付の差が使用されます
  • freq:PeriodIndexオブジェクトの頻度。有効な頻度の例としては、'D'(日)、'M'(月)、'Y'(年)などがあります
  • name:PeriodIndexオブジェクトの名前

pd.period_range()を使ってyyyy-MMを取得する

freq引数で'M'を指定することでyyyy-MMを取得することができます。

pd.period_range(start='2017-01-01', end='2018-01-01', freq='M')

出力結果

PeriodIndex(['2017-01', '2017-02', '2017-03', '2017-04', '2017-05', '2017-06',
             '2017-07', '2017-08', '2017-09', '2017-10', '2017-11', '2017-12',
             '2018-01'],
            dtype='period[M]')

こんな感じでyyyy-MM形式で取得できます。日付を扱う他のメソッドなどと比較して何がうれしいかというと、日付の日(day)の情報がないことです。pd.date_range()でも似たようなことができますが、yyyy-MM-ddのように日(day)の情報を持っていたり、時間の情報を持っていることもあり、それらを除く処理が必要になります。pd.period_range()を使えばその除く処理が不要になります。なのでコードが短くなってわかりやすくなり、メンテナンスやデバックなどがしやすくなって嬉しいと考えます。

ファイルを順番に読み込む

index_year_month=pd.period_range(start='2017-01-01', end='2018-01-01', freq='M', name='test')

for d in index_year_month:
    df=pd.read_parquet(f'./GA_log/{str(d)}.parquet')
    '''
    以下、何かしらの処理
    '''

これにより、GA_logディレクトリ内のparquetファイルが順番に読み込まれます。

【Python】pd.date_range()で指定した範囲の日付を取得

pandas.date_range()とは

pandas.date_range()は、pandasライブラリの関数で、datetime型のindexを作成するために使用されます。戻り値はDatetimeIndexオブジェクトであり、生成された日付がインデックスとして格納されます。この関数は、start引数とend引数を指定することで、その期間内のdatetime型のindexを作成することができます。また、freq引数を使用して、indexの頻度を指定することもできます。

指定した範囲の連続した日付を取得する

以下のように記述することで、2023年4月1日から2023年4月30日までの連続した日付を生成することができます。

dates = pd.date_range(start='2023-04-01', end='2023-04-30')
print(dates)

実行結果

DatetimeIndex(['2023-04-01', '2023-04-02', '2023-04-03', '2023-04-04',
               '2023-04-05', '2023-04-06', '2023-04-07', '2023-04-08',
               '2023-04-09', '2023-04-10', '2023-04-11', '2023-04-12',
               '2023-04-13', '2023-04-14', '2023-04-15', '2023-04-16',
               '2023-04-17', '2023-04-18', '2023-04-19', '2023-04-20',
               '2023-04-21', '2023-04-22', '2023-04-23', '2023-04-24',
               '2023-04-25', '2023-04-26', '2023-04-27', '2023-04-28',
               '2023-04-29', '2023-04-30'],
              dtype='datetime64[ns]', freq='D')

name引数を指定するとDataFrameにするときに便利

pandas.date_range()関数の引数には、name引数があります。name引数は、DatetimeIndexオブジェクトの名前を指定するために使用されます。name引数は省略可能で、デフォルト値はNoneです。name引数を使って名前を指定すると、DataFrameを作るときに名前がcolumn名になるため便利です。

以下のように記述することで、column名がdateで中身が2023年4月1日から2023年4月30日までの連続した日付のDataFrameを生成することができます。

dates = pd.date_range(start='2023-04-01', end='2023-04-30', name='date')
pd.DataFrame(dates)

実行結果

date
0 2023-04-01
1 2023-04-02
2 2023-04-03
3 2023-04-04
4 2023-04-05
5 2023-04-06
6 2023-04-07
7 2023-04-08
8 2023-04-09
9 2023-04-10
10 2023-04-11
11 2023-04-12
12 2023-04-13
13 2023-04-14
14 2023-04-15
15 2023-04-16
16 2023-04-17
17 2023-04-18
18 2023-04-19
19 2023-04-20
20 2023-04-21
21 2023-04-22
22 2023-04-23
23 2023-04-24
24 2023-04-25
25 2023-04-26
26 2023-04-27
27 2023-04-28
28 2023-04-29
29 2023-04-30

日付のマスタを作成したいときに役立ちそうです。

freq引数を使って指定した範囲の月初の日付を取得する

freq引数は、生成する日付の間隔を指定するために使用されます。freq引数は省略可能で、デフォルト値は’D’です。freq引数には、‘D’(日)、‘H’(時間)、‘T’(分)、‘S’(秒)、‘L’(ミリ秒)、‘U’(マイクロ秒)、‘N’(ナノ秒)などがあります。月初の日付を取得する場合は‘MS’を指定します。

以下のように記述することで20223年の毎月の月初の日付を所得できます。

pd.date_range(start='2023-01-01', end='2023-12-01', freq='MS')

実行結果

DatetimeIndex(['2023-01-01', '2023-02-01', '2023-03-01', '2023-04-01',
               '2023-05-01', '2023-06-01', '2023-07-01', '2023-08-01',
               '2023-09-01', '2023-10-01', '2023-11-01', '2023-12-01'],
              dtype='datetime64[ns]', freq='MS')

ちなみにstart引数とend引数にはどの日(day)を入れても、freq引数が'MS'ならば、月初の日付を取得することになります。

pd.date_range(start='2023-01-15', end='2023-12-31', freq='MS')

実行結果

DatetimeIndex(['2023-02-01', '2023-03-01', '2023-04-01', '2023-05-01',
               '2023-06-01', '2023-07-01', '2023-08-01', '2023-09-01',
               '2023-10-01', '2023-11-01', '2023-12-01'],
              dtype='datetime64[ns]', freq='MS')

freq引数を使って指定した範囲のn日毎の日付を取得する

freq引数を使うことで、n日毎の日付けを取得することができます。 例えば7日毎の日付を取得する場合は下記のように記述します。

pd.date_range(start='2023-04-01', end='2023-04-30', freq='7D')

実行結果

DatetimeIndex(['2023-04-01', '2023-04-08', '2023-04-15', '2023-04-22',
               '2023-04-29']

参考

沖縄って東京より暑いの?

こういったtweetなんかもあって、沖縄と東京どっちあが暑いんだ?と思うようになり、実際どうなのか気象庁のデータを使ってみて沖縄と東京のどちらが暑いのかを何となく確認します。

対象データ

期間:2000年から2021年までの8月
元データ:気象庁 Japan Meteorological Agency(urlの詳細はコードに記載)
沖縄:那覇市のデータを用います
東京:大手町あたりのようです(詳しくはこちら

コード

import

import pandas as pd
import numpy as np 
import re
import time
import matplotlib.pyplot as plt
import seaborn as sns
import japanize_matplotlib

関数

マルチカラムをシングルカラムで取得
def get_converted_multi_columns(df):
    return ['_'.join(pd.unique(i).tolist()) for i in df.columns.values]
気象データのurlを取得
def base_path(prec_no, block_no, year):
    path=f'https://www.data.jma.go.jp/obd/stats/etrn/view/daily_s1.php?prec_no={prec_no}&block_no={block_no}&year={year}&month=8&day=&view=p1'
    return path

prec_noとblock_noは場所を示す情報を、yearには取得する西暦を渡します。

置換とfloat型へ変換
def replace_to_float(series):
    result=(series
            .astype(str)
            .replace(re.compile(r" \)$")
                     , ''
                     , regex=True)
            .astype(float)
            )

float型で入ると思っている列で文字列として入り、かつ不要な文字「' )'」が入っていることがあり、それを解消するための関数

気象データを取得
def temperature_august(years, location_info):
    lst_df_temperature=[]
    _TIME_SLEEP=5
    for year in years:
        time.sleep(_TIME_SLEEP)
        prec_no, block_no, location=location_info
        url=base_path(prec_no, block_no, year)
        # 各西暦の8月のURL
        lst_df_read_html=pd.read_html(url)
        df_mult=lst_df_read_html[0]
        # マルチカラムを紐解く
        col=get_converted_multi_columns(df_mult)
        df_mult.columns = col
        # 西暦と場所のカラムを追加
        df=(df_mult
            .assign(year=year)
            .assign(location=location)
           )
        lst_df_temperature.append(df)
    # dfが入っているlistをコンキャットさせてインデックスを振りなおしてreturn
    return pd.concat(lst_df_temperature).reset_index(drop=True)

ウェブサイトからデータを取得してマルチカラムをシングルカラムにしたり、DataFrameに西暦と場所の列を追加し作成ています。

西暦のリストを作成

# 2000年から2021までの西暦を取得
YEAR_START=2000
YEAR_END=2021
lst_year = [ str(i) for i in range(YEAR_START,YEAR_END+1)]

場所の情報

# 数字はurlの情報で必要になり、文字列はDataframeの列に追加するために使用する
okinawa=[91, 47936, "okinawa"]
tokyo=[44, 47662, "tokyo"]

データを取得

df_okinawa=temperature_august(lst_year, okinawa)
df_tokyo=temperature_august(lst_year, tokyo)

データの微修正

# indexを振りなおす
df=(pd.concat([df_okinawa,df_tokyo])
    .reset_index(drop=True)
   )
# 気温(℃)_最高の列に不要なもの(' )')が含まれているので削除してfloat型へ
df['気温(℃)_最高']=replace_to_float(df['気温(℃)_最高'])
df['気温(℃)_最低']=replace_to_float(df['気温(℃)_最低'])

平均気温の比較

sns.relplot(x='year'
            , y='気温(℃)_平均'
            , data=df
            , kind='line'
            , hue="location"
            , height=8, aspect=2.3
            , legend=False
            , ci='sd')
plt.ylim(0,40)
plt.ylabel("平均気温(℃)", fontsize=24)
plt.xlabel("西暦", fontsize=24)
plt.tick_params(labelsize=18)
plt.text(21.2,28.1,'沖縄',c='tab:blue',fontsize=20)
plt.text(21.2,26.6,'東京',c='tab:orange',fontsize=20)
plt.show()

沖縄と東京の平均気温の比較

最高気温の比較

sns.relplot(x='year'
            , y='気温(℃)_最高'
            , data=df
            , kind='line'
            , hue="location"
            , height=8, aspect=2.3
            , legend=False
            , ci='sd')
plt.ylim(0,40)
plt.ylabel("最高気温(℃)", fontsize=24)
plt.xlabel("西暦", fontsize=24)
plt.tick_params(labelsize=18)
plt.text(21.2,30.1,'沖縄',c='tab:blue',fontsize=20)
plt.text(21.2,32.0,'東京',c='tab:orange',fontsize=20)
plt.show()

沖縄と東京の最高気温の比較

最低気温の比較

sns.relplot(x='year'
            , y='気温(℃)_最低'
            , data=df
            , kind='line'
            , hue="location"
            , height=8, aspect=2.3
            , legend=False
            , ci='sd')
plt.ylim(0,40)
plt.ylabel("最高最低(℃)", fontsize=24)
plt.xlabel("西暦", fontsize=24)
plt.tick_params(labelsize=18)
plt.text(21.2,26.1,'沖縄',c='tab:blue',fontsize=20)
plt.text(21.2,23.6,'東京',c='tab:orange',fontsize=20)
plt.show()

沖縄と東京の最低気温の比較

所感

どちらが暑いかは何とも言えない感じになったかなという印象。
最低気温は沖縄と比較して東京のほうが涼しいかも。
沖縄は大体同じような気温が多い。 東京は気温の変化が大きい。
└日毎も日内変動も変化が大きそう

最高気温

最高気温は特にどちらが暑いかは言えなさそう。東京と比較すると沖縄は最高気温の変化(幅)が少なく大体同じような最高気温。東京は暑い時もあれば、比較的厚さが和らいでいる日もある。

最低気温

東京のほうが最低気温は低そう。ただし日毎の変化が大きいのでもしかしたら沖縄よりも最低気温が高い日があるかも。

まとめ

最低気温は東京のほうが涼しいけど最高気温と平均気温は沖縄も東京も似たような感じになるかもね。だけど東京は日毎の気温の変化が大きいので日によっては東京のほうが涼しい日もあれば暑い日もありそうだねって感じでしたー

【R】for文でdate型のベクトルを使うときのTIPS

date型のベクトルをfor文で繰り返し処理をするときに工夫が必要だったのでその対応方法をまとめました。

理由はわからないが、date型のベクトルから要素をfor文で取得するとnumeric型で取得してしまうらしいです。対応方法として思いついたのはseq_along()を使う方法。

seq_alongに関する公式ドキュメントは下記。 www.rdocumentation.org

日付のベクトルを作成

まずは日付のベクトルvctを作成します。

s_d='2022-01-01'
e_d='2022-12-01'
vct <- seq(as.Date(s_d), as.Date(e_d), by='month')

seq()について

seq()を使うことで連続する値や日付をベクトルで取得することができます。 以下に簡単な例を示します。

seq(x, y)で、x から y までの連続する値を取得できます。

vct_1 = seq(1,11)
vct_1

seq(x, y, by=z)で、 x から y までを z の値ごとに取得できます。

vct_2 = seq(1,11, by=2)
vct_2

seq(x, y, by=z)で、xとyを日付にすることで連続する日付を取得することができます。また、zには「day」「month」「year」のいずれかを入れます。dayであれば連続する日付、monthであれば連続する月の日付、yearであれば、連続する年の日付が取得できます。

# by='day'
seq(as.Date('2022-01-01'), as.Date('2022-01-05'), by='day')

# by='month'
seq(as.Date('2022-01-01'), as.Date('2022-05-01'), by='month')

# by='year'
seq(as.Date('2022-01-01'), as.Date('2026-01-01'), by='year')

ベクトルからfor文で要素を日付型として取得する

日付の入ったvctからfor文で要素を日付型として取得するには、seq_along()を使い要素の番号を取得してベクトルの位置を指定するやり方が一つの方法です。

for (x in seq_along(vct)){
    print(vct[x])
}

下記のように要素をそのまま取り出すとdate型ではなくnumeric型として取得することになります。

for (d in vct){
    print(d)
}

seq_along()以外にもっと賢い方法があるのかもしれないけどこれしか思いつきませんでした。詳しい人がいたら教えてくださいm(__)m

Rでfor文を使って処理した結果を新しいベクトルに追加

Rでfor文を使って処理した結果を新しいベクトルに追加するのに躓いたので書き留めておきます。わかりやすくするためにいろいろ寄り道するように書いてあります。

今回はfor文を使ってvctという変数に対して各要素に2倍した値を新しいベクトルに追加してみたいと思います。

※ for文を使わなくてもできますが、目的がfor文を理解するために内容が簡単なものをあえて使用しています

※ Jupyter notebookで行っているためもしかしたらRStudioだとエラーが発生するところがあるかもしれません

Rでfor文を書く

for文は繰り返し処理をするときに使います。今回は繰り返しの範囲はベクトルを使います。他にも数字で範囲を指定・リストを使うなどがあると思います。

まずは、ベクトルを作りたいと思います。

# 中身に意味はなく適当です
vct <- c(2, 5, 6, 7)

for文を理解するための寄り道として、変数vctの中身を一つずつprintするコードを書いてみます。

基本的な書き方は下記です。

for (要素 in ベクトル){
    print(要素)
}

では実際に上記の変数vctの要素をprintしていきます。

# 例1
for (x in vct){
    print(x)
}
# -----------------
[1] 2
[1] 5
[1] 6
[1] 7

こんな感じでベクトルの要素を一つずつxに入れてprintすることができます。

もう一つ例を載せておきます。

# 例2
vct_name <- c("ito", "sato", "goto", "muto", "gondo")

for (name in vct_name){
    print(name)
}
# -----------------
[1] "ito"
[1] "sato"
[1] "goto"
[1] "muto"
[1] "gondo"

ベクトルに要素を追加する

ベクトルに要素を追加するにはappend()を使うことで実現できます。

上で作成したvctに10を追加する場合はこのように書きます。

vct <- append(vct,10)

vctをprintすると10が追加されているのがわかります。

print(vct)
# -----------------
[1]  2  5  6  7 10

for文を使って処理した結果をベクトルに追加

本題の「for文を使ってvctという変数に対して各要素に2倍した値を新しいベクトルに追加」をしたいと思います。

# 空のベクトルを用意
vct_2 <- c()
for (num in vct){
    # numを2倍したものをappend_numに入れる
    append_num <- num * 2
    # append_numをvct_2に追加してvct_2を上書きする
    vct_2 <- append(vct_2, append_num)
}
print(vct_2 )
# -----------------
[1]  4 10 12 14 20

まずは、処理した結果(各要素を2倍したもの)を追加していく先の空のベクトルを作成します。今回は「vct_2」という変数名の空のベクトルを作成しています。

そして、処理する前の値が入っているvctの中身をfor文で順番に出すためのコード「for (num in vct){}」を書きます。これでnumにはvctの要素が順番に入っていきます。numを2倍しているのが「num * 2」という個所になります。num * 2の結果はappend_numに入れています。

最後に新しいベクトルであるvct_2にappend_num を追加していくコードを書きます。それが「vct_2 <- append(vct_2, append_num)」の箇所になります。append()の使い方としてはappend(追加先のベクトル, 追加する要素)といった感じです。ちなみに、「vct_2 <- append(vct_2, append_num)」の「vct_2 <- 」の部分は上書き保存をするイメージです。「append(vct_2, append_num)」だけでは、vct_2に新しく要素は追加されるが上書き保存されないので、新しく要素が追加された状態のvct_2にはなりません(excelで作業して保存しないで閉じるみたいな感じです)。

上書き保存しない例はこんな感じ

append(vct_2, 100)
# -----------------
4 10 12 14 20 100

見た感じ100が追加されていそうではあるが、vct_2をprintすると100が追加されていないことがわかる。

print(vct_2)
# -----------------
[1]  4 10 12 14 20

最後に

まぁ、ぶっちゃけ各要素を2倍したものはもっと簡単に書けます。

print(vct*2)
# -----------------
[1]  4 10 12 14 20

ですが、プログラミング初学者の方などがfor文を理解しやすいようにするために今回は重視するためにfor文を使いました。