質問するログイン新規登録

回答編集履歴

2

追記

2017/11/17 06:35

投稿

mkgrei
mkgrei

スコア8562

answer CHANGED
@@ -8,7 +8,7 @@
8
8
  ```
9
9
 
10
10
  コードの速さが気になるのであれば、numpy.arrayへのキャストなくすべきでしょう。
11
- それも7〜8倍程度です
11
+ また検索があるの、listやnp.arrayはなくsetを使うとだいぶ早くなります。
12
12
  ```python
13
13
  import math
14
14
  import pandas as pd
@@ -16,7 +16,7 @@
16
16
  grundy_ceil = [0]
17
17
 
18
18
  for n in range(1, 101):
19
- a = [grundy_ceil[n - i] for i in range(1, math.ceil(n /2 + 1))]
19
+ a = set([grundy_ceil[n - i] for i in range(1, math.ceil(n /2 + 1))])
20
20
  grundy_ceil.append(next(i for i in count() if i not in a))
21
21
 
22
22
  df = pd.DataFrame(grundy_ceil).T
@@ -24,6 +24,9 @@
24
24
 
25
25
  ---
26
26
  追記:完全に趣味ですが。[ここ](https://stackoverflow.com/questions/7088625/what-is-the-most-efficient-way-to-check-if-a-value-exists-in-a-numpy-array)を参考に。
27
+ yag1kazさんのlistからの取り出し方も取り入れました。
28
+ sliceをリスト内包表記で書くと遅くなるのは盲点でした…
29
+
27
30
  ```python
28
31
  from timeit import timeit
29
32
  from itertools import count
@@ -74,14 +77,42 @@
74
77
  df = pd.DataFrame(grundy_ceil).T
75
78
  return df
76
79
 
80
+ def f4():
81
+ grundy_ceil = [0]
82
+ for n in range(1, 101):
83
+ a = set(grundy_ceil[:-math.ceil(n/2+1):-1])
84
+ j = next(i for i in count() if i not in a)
85
+ grundy_ceil.append(j)
86
+ df = pd.DataFrame(grundy_ceil).T
87
+ return df
88
+
89
+ a = f0()
90
+ b = f1()
91
+ c = f2()
92
+ d = f3()
93
+ e = f4()
94
+ print('f1', np.allclose(a[0].values, b[0].values))
95
+ print('f2', np.allclose(a[0].values, c[0].values))
96
+ print('f3', np.allclose(a[0].values, d[0].values))
97
+ print('f4', np.allclose(a[0].values, e[0].values))
98
+ '''
99
+ 一応同じ結果になることを確認
100
+ f1 True
101
+ f2 True
102
+ f3 True
103
+ f4 True
104
+ '''
77
105
  n = 1000
78
- print('Original {}'.format(timeit(f0, number=n)))
106
+ print('Original {}'.format(timeit(f0, number=n)))
79
- print('list {}'.format(timeit(f1, number=n)))
107
+ print('list {}'.format(timeit(f1, number=n)))
80
- print('np.array {}'.format(timeit(f2, number=n)))
108
+ print('np.array {}'.format(timeit(f2, number=n)))
81
- print('set {}'.format(timeit(f3, number=n)))
109
+ print('set {}'.format(timeit(f3, number=n)))
82
-
110
+ print('slice+set {}'.format(timeit(f4, number=n)))
111
+ '''
83
- # Original 9.262939481996
112
+ Original 9.65767323700129
84
- # list 1.147810668015154
113
+ list 1.1692692330107093
85
- # np.array 7.4433728019939736
114
+ np.array 7.38920716199209
86
- # set 0.8586325150099583
115
+ set 0.9272018460032996
116
+ slice+set 0.6420557640085462
117
+ '''
87
118
  ```

1

追記

2017/11/17 06:34

投稿

mkgrei
mkgrei

スコア8562

answer CHANGED
@@ -20,4 +20,68 @@
20
20
  grundy_ceil.append(next(i for i in count() if i not in a))
21
21
 
22
22
  df = pd.DataFrame(grundy_ceil).T
23
+ ```
24
+
25
+ ---
26
+ 追記:完全に趣味ですが。[ここ](https://stackoverflow.com/questions/7088625/what-is-the-most-efficient-way-to-check-if-a-value-exists-in-a-numpy-array)を参考に。
27
+ ```python
28
+ from timeit import timeit
29
+ from itertools import count
30
+ import math
31
+ import pandas as pd
32
+ import numpy as np
33
+
34
+ pd.options.display.max_columns = None
35
+ pd.options.display.notebook_repr_html = True
36
+
37
+ def f0():
38
+ grundy_ceil = np.array([0])
39
+ #grundy_ceil_1p = np.array([0])
40
+ for n in range(1, 101):
41
+ compare = np.array([])
42
+ compare = np.append(compare, [grundy_ceil[n - i] for i in range(1, math.ceil(n /2 + 1))])
43
+ for j in range(compare.size + 1):
44
+ if not j in compare:
45
+ grundy_ceil = np.append(grundy_ceil, j)
46
+ break
47
+ df = pd.DataFrame(grundy_ceil).T
48
+ return df
49
+
50
+ def f1():
51
+ grundy_ceil = [0]
52
+ for n in range(1, 101):
53
+ a = [grundy_ceil[n - i] for i in range(1, math.ceil(n /2 + 1))]
54
+ j = next(i for i in count() if i not in a)
55
+ grundy_ceil.append(j)
56
+ df = pd.DataFrame(grundy_ceil).T
57
+ return df
58
+
59
+ def f2():
60
+ grundy_ceil = [0]
61
+ for n in range(1, 101):
62
+ a = np.array([grundy_ceil[n - i] for i in range(1, math.ceil(n /2 + 1))])
63
+ j = next(i for i in count() if i not in a)
64
+ grundy_ceil.append(j)
65
+ df = pd.DataFrame(grundy_ceil).T
66
+ return df
67
+
68
+ def f3():
69
+ grundy_ceil = [0]
70
+ for n in range(1, 101):
71
+ a = set([grundy_ceil[n - i] for i in range(1, math.ceil(n /2 + 1))])
72
+ j = next(i for i in count() if i not in a)
73
+ grundy_ceil.append(j)
74
+ df = pd.DataFrame(grundy_ceil).T
75
+ return df
76
+
77
+ n = 1000
78
+ print('Original {}'.format(timeit(f0, number=n)))
79
+ print('list {}'.format(timeit(f1, number=n)))
80
+ print('np.array {}'.format(timeit(f2, number=n)))
81
+ print('set {}'.format(timeit(f3, number=n)))
82
+
83
+ # Original 9.262939481996
84
+ # list 1.147810668015154
85
+ # np.array 7.4433728019939736
86
+ # set 0.8586325150099583
23
87
  ```