LoginSignup
1
2

More than 3 years have passed since last update.

VBAユーザがPython・Rを使ってみた:簡単なプログラムの例

Last updated at Posted at 2021-01-24

はじめに

機械学習の勉強を始めたVBAユーザです。
備忘録としてPython・Rの文法をVBAと比較しながらまとめていきたいと思います。

今回は、簡単なプログラムをそれぞれの言語で書いてみたいと思います。

目次

簡単なプログラムの例

簡単な定義の数列を書き出すプログラムの例です。

偶数と奇数

0から10までの偶数(even number)と奇数(odd number)をそれぞれ定義どおり計算して書き出すプログラムを書いてみます。
定義:
偶数は、2で割り切れる整数のこと。
奇数は、2で割り切れない整数のこと。

Python

Python3
# 0から10までの偶数を書き出す
for n in range(0, 10+1):
    if n % 2 == 0:
        print(n)
# 0
# 2
# 4
# 6
# 8
# 10

# 0から10までの奇数を書き出す
for n in range(0, 10+1):
    if n % 2 == 1:
        print(n)
# 1
# 3
# 5
# 7
# 9

R

R
# 0から10までの偶数を書き出す
for (n in 0:10) {
  if (n %% 2 == 0) {
    print(n)
  }
}
# [1] 0
# [1] 2
# [1] 4
# [1] 6
# [1] 8
# [1] 10

# 0から10までの奇数を書き出す
for (n in 0:10) {
  if (n %% 2 == 1) {
    print(n)
  }
}
# [1] 1
# [1] 3
# [1] 5
# [1] 7
# [1] 9

VBA

VBA
Dim n As Integer

' 0から10までの偶数を書き出す
For n = 0 To 10
  If n Mod 2 = 0 Then
    Debug.Print n
  End If
Next n
' 0
' 2
' 4
' 6
' 8
' 10

' 0から10までの奇数を書き出す
For n = 0 To 10
    If n Mod 2 = 1 Then
        Debug.Print n
    End If
Next n
' 1
' 3
' 5
' 7
' 9

別の書き方

いくつか別の書き方をしてみます。

リスト内包表記

Pythonのリスト内包表記を使うとこのように簡潔に書けます。

Python3
[n for n in range(0, 10+1) if n % 2 == 0]
# [0, 2, 4, 6, 8, 10]

[n for n in range(0, 10+1) if n % 2 == 1]
# [1, 3, 5, 7, 9]

これらはそれぞれ次のコードと等価です:

Python3
nums = []
for n in range(0, 10+1):
    if n % 2 == 0:
        nums.append(n)
nums
# [0, 2, 4, 6, 8, 10]

nums = []
for n in range(0, 10+1):
    if n % 2 == 1:
        nums.append(n)
nums
# [1, 3, 5, 7, 9]

ベクトルの演算

Rのベクトルの演算を使うとこのように書けます。

R
v <- 0:10

v %% 2 == 0
#  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE
v[v %% 2 == 0]
#  0  2  4  6  8 10

v %% 2 == 1
# FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE
v[v %% 2 == 1]
#  1 3 5 7 9

Pythonでも、Numpy の numpy.ndarray を使うと同じように書けます。

Python3
import numpy as np
v = np.arange(0, 10+1)

print(v % 2 == 0)
# [ True False  True False  True False  True False  True False  True]
list(v[v % 2 == 0])
# [0, 2, 4, 6, 8]

print(v % 2 == 1)
# [False  True False  True False  True False  True False  True False]
list(v[v % 2 == 1])
# [1, 3, 5, 7, 9]

等差数列として

定義からそのまま計算したものではなくなりますが、等差数列になることを考えれば、もちろんこのようにも書けます。

Python3
list(range(0, 10+1, 2))
# [0, 2, 4, 6, 8, 10]
list(np.arange(0, 10+1, 2))
# [0, 2, 4, 6, 8, 10]

list(range(1, 10+1, 2))
# [1, 3, 5, 7, 9]
list(np.arange(1, 10+1, 2))
# [1, 3, 5, 7, 9]
R
seq(0, 10, by=2)
#  0  2  4  6  8 10
seq(1, 10, by=2)
# 1 3 5 7 9

一般項を求めてリスト内包表記で

また、一般項を考えればもちろんこのようにも書けます。
$a_n = a_1 + (n-1)*2$

Python3
[0 + (n-1)*2 for n in range(1,10+1) if 0 + (n-1)*2 <= 10]
# [0, 2, 4, 6, 8, 10]

[1 + (n-1)*2 for n in range(1,10+1) if 1 + (n-1)*2 <= 10]
# [1, 3, 5, 7, 9]

一般項を求めてベクトルの演算で

Python3
import numpy as np

v = 0 + np.arange(0, 10+1) * 2
list(v[v <= 10])
# [0, 2, 4, 6, 8, 10]

v = 1 + np.arange(0, 10+1) * 2
list(v[v <= 10])
# [1, 3, 5, 7, 9]
R
v <- 0 + 0:10 * 2
v[v <= 10]
#  0  2  4  6  8 10

v <- 1 + 0:10 * 2
v[v <= 10]
# 1 3 5 7 9

素数

1から50までの素数(prime number)を書き出してみます。
定義:
素数は、1より大きい自然数で、正の約数が1と自分自身のみであるもののこと。正の約数の個数が2である自然数と言い換えることもできる。

Python

Python3
# 1から50までの素数を書き出す
for n in range(1, 50+1):
    count = 0
    for m in range(1, n+1):
        if n % m == 0:
            count += 1
    if count == 2:
        print(n, end=' ')
print()   # 改行
# 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 

R

R
# 1から50までの素数を書き出す
for (n in 1:50) {
  count <- 0
  for (m in 1:n) {
    if (n %% m == 0) {
      count = count + 1
    }
  }
  if (count == 2) {
    cat(n, "")
  }
}
# 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 

VBA

VBA
Dim n As Integer
Dim m As Integer
Dim count As Integer

' 1から50までの素数を書き出す
For n = 1 To 50
    count = 0
    For m = 1 To n
        If n Mod m = 0 Then
            count = count + 1
        End If
    Next m
    If count = 2 Then
        Debug.Print n;
    End If
Next n
Debug.Print ""   ' 改行
' 2  3  5  7  11  13  17  19  23  29  31  37  41  43  47

等差数列

初項 $a_1=1$、公差 $d=2$ の等差数列(arithmetic sequence)の最初の10項を書き出してみます。
定義:
初項 $a_1$、公差 $d$ の等差数列 $a_n$ は、次の漸化式で定義される:

\begin{eqnarray*}
a_n &=& a_1 &(n = 1) \\
a_n &=& a_{n-1} + d \quad &(n \geq 2)
\end{eqnarray*} \\

Python

Python3
# 初項a1=1、公差d=2の等差数列の最初の10項を書き出す
a1 = 1
d = 2
for n in range(1, 10+1):
    if n == 1:
        an = a1
    else:
        an += d
    print(an, end=' ')
print()   # 改行
# 1 3 5 7 9 11 13 15 17 19 

R

R
# 初項a1=1、公差d=2の等差数列の最初の10項を書き出す
a1 <- 1
d <- 2
for (n in 1:10) {
  if (n == 1) {
    an <- a1
  } else {
    an <- an + d
  }
  cat(an, "")
}
# 1 3 5 7 9 11 13 15 17 19 

VBA

VBA
Dim n As Integer
Dim a1 As Integer
Dim d As Integer
Dim an As Integer

' 初項a1=1、公差d=2の等差数列の最初の10項を書き出す
a1 = 1
d = 2
For n = 1 To 10
    If n = 1 Then
        an = a1
    Else
        an = an + d
    End If
    Debug.Print an;
Next n
Debug.Print ""   ' 改行
' 1  3  5  7  9  11  13  15  17  19

別の書き方

別の書き方をしてみます。

等比数列なので

Python、Rには等比数列を作る関数がありますので、

Python3
list(range(a1, a1+(10-1)*d+1, d))
# [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
R
seq(a1, a1+(10-1)*d, by=2)
#  1  3  5  7  9 11 13 15 17 19

一般項を求めてリスト内包表記で

一般項は $a_n = a_1 + (n-1)d$ ですので、

Python3
a1 = 1
d = 2
[a1 + (n-1)*d for n in range(1, 10+1)]
# [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]

一般項を求めてベクトルの演算で

Python3
a1 = 1
r = 2
import numpy as np
ns = np.arange(1, 10+1)
print(ns)
# [ 1  2  3  4  5  6  7  8  9 10]
v = a1 + (ns - 1) * d
list(v)
# [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]

v = a1 + (np.arange(1, 10+1) - 1) * d
list(v)
# [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
R
a1 <- 1
d <- 2
ns <- 1:10
a1 + (ns - 1) * d
#  1  3  5  7  9 11 13 15 17 19
a1 + (1:10 - 1) * d
#  1  3  5  7  9 11 13 15 17 19

等比数列

初項 $a_1=1$、公差 $r=2$ の等比数列(geometric sequence)の1000以下の項を書き出してみます。
定義:
初項 $a_1$、公比 $r$ の等差数列 $a_n$ は、次の漸化式で定義される:

\begin{eqnarray*}
a_n &=& a_1 &(n = 1) \\
a_n &=& a_{n-1} * r \quad &(n \geq 2)
\end{eqnarray*} \\

Python

Python3
# 初項a1=1、公比r=2の等比数列の1000以下の項を書き出す
a1 = 1
r = 2
an = a1
while an <= 1000:
    print(an, end=' ')
    an *= r
print()   # 改行
# 1 2 4 8 16 32 64 128 256 512 

R

R
# 初項a1=1、公比r=2の等比数列の1000以下の項を書き出す
a1 <- 1
r <- 2
an <- a1
while (an <= 1000) {
  cat(an, "")
  an <- an * r
}
# 1 2 4 8 16 32 64 128 256 512 

VBA

VBA
Dim n As Integer
Dim a1 As Integer
Dim r As Integer
Dim an As Integer

' 初項a1=1、公比r=2の等比数列の1000以下の項を書き出す
a1 = 1
r = 2
an = a1
Do While an <= 1000
    Debug.Print an;
    an = an * r
Loop
Debug.Print ""   ' 改行
' 1  2  4  8  16  32  64  128  256  512

別の書き方

別の書き方をしてみます。

一般項を求めてリスト内包表記で

一般項は $a_n = a_1 r^{n-1}$ ですので、

Python3
a1 = 1
r = 2
[a1 * r**(n-1) for n in range(1, 20+1) if a1 * r**(n-1) <= 1000]
# [1, 2, 4, 8, 16, 32, 64, 128, 256, 512]

注意)range(1, 20+1)20は適当に大きな数。以下も同様。

一般項を求めてベクトルの演算で

Python3
a1 = 1
r = 2
import numpy as np
ns = np.arange(1, 20+1)
print(ns)
# [ 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20]
v = a1 * r**(ns - 1)
list(v[v <= 1000])
# [1, 2, 4, 8, 16, 32, 64, 128, 256, 512]

v = a1 * r**(np.arange(1, 20+1) - 1)
list(v[v <= 1000])
# [1, 2, 4, 8, 16, 32, 64, 128, 256, 512]
R
a1 <- 1
r <- 2
ns <- 1:20
v <- a1 * r^(ns - 1)
v[v <= 1000]
#   1   2   4   8  16  32  64 128 256 512
v <- a1 * r^(1:20 - 1)
v[v <= 1000]
#   1   2   4   8  16  32  64 128 256 512

フィボナッチ数

フィボナッチ数(Fibonacci number)を書き出す例です。Python チュートリアル にあるです。
定義:
フィボナッチ数列 $F_n (n \geq 0)$ は、次の漸化式で定義される:

\begin{eqnarray*}
F_0 &=& 0 &(n = 0) \\
F_1 &=& 1 &(n = 1) \\
F_{n+2} &=& F_n + F_{n+1} \quad &(n \geq 0)
\end{eqnarray*} \\

Python
Pythonでは、複数同時の代入 (multiple assignment) ができるので、他の言語より少し簡単に書けます。

Python3
# フィボナッチ数列の1000以下の項を書き出す
f0 = 0
f1 = 1
fn = f0
fnp1 = f1
while fn <= 1000:
    print(fn, end=' ')
    fnp2 = fn + fnp1
    fn = fnp1
    fnp1 = fnp2
print()   # 改行
# 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 

fn, fnp1 = f0, f1
while fn <= 1000:
    print(fn, end=' ')
    fn, fnp1 = fnp1, fn+fnp1
print()   # 改行
# 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 

R

R
# フィボナッチ数列の1000以下の項を書き出す
f0 <- 0
f1 <- 1
fn <- f0
fnp1 <- f1
while (fn <= 1000) {
  cat(fn, "")
  fnp2 <- fn + fnp1
  fn <- fnp1
  fnp1 <- fnp2
}
# 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 

VBA

VBA
Dim f0 As Integer
Dim f1 As Integer
Dim fn As Integer
Dim fnp1 As Integer
Dim fnp2 As Integer

' フィボナッチ数列の1000以下の項を書き出す
f0 = 0
f1 = 1
fn = f0
fnp1 = f1
Do While fn <= 1000
    Debug.Print fn;
    fnp2 = fn + fnp1
    fn = fnp1
    fnp1 = fnp2
Loop
Debug.Print ""   ' 改行
' 0  1  1  2  3  5  8  13  21  34  55  89  144  233  377  610  987
1
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
1
2