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

質問編集履歴

1

追記

2020/09/24 15:15

投稿

yuudai
yuudai

スコア65

title CHANGED
File without changes
body CHANGED
@@ -1,4 +1,168 @@
1
1
  datetime型の要素を持つ列をlist型に変換するにはどうすればいいですか?
2
2
  .values.tolist()とすると全部NaNになってしまいます。
3
3
 
4
- そもそものやりたいことは、もともとあるデータフレーム(時系列データ)から新しくデータを作って元のデータとつなげたいのですが、その作ったデータが元のデータと長さが少し異なっていてどこでずれているかわからないのでmerge()で結合する際に'Time'という列をキーにしてつなげたいのです。また'Time'をリストにしてfor文で一行ずつ取り出したいです。データフレームのまま扱おうとすると列を指定したときにIndexError: string index out of rangeこのようなエラーが出るのでリストにしたいです。
4
+ そもそものやりたいことは、もともとあるデータフレーム(時系列データ)から新しくデータを作って元のデータとつなげたいのですが、その作ったデータが元のデータと長さが少し異なっていてどこでずれているかわからないのでmerge()で結合する際に'Time'という列をキーにしてつなげたいのです。また'Time'をリストにしてfor文で一行ずつ取り出したいです。データフレームのまま扱おうとすると列を指定したときにIndexError: string index out of rangeこのようなエラーが出るのでリストにしたいです。
5
+
6
+ サンプルコード
7
+
8
+ うまい説明の仕方がわからないのでコード全部乗っけます。
9
+
10
+ 時系列データのサンプルデータをどうやって用意すればいいかわかりませんがoandaapiでこのようなデータを用意します。
11
+ ![イメージ説明](683ffd1088a406ba6054ad9f31f7bd17.png)
12
+ ```ここに言語を入力
13
+ #トレンドラインを計算する
14
+ # 高値の始点/支点を取得
15
+ def get_highpoint(start, end):
16
+ chart = df[start:end+1]
17
+ while len(chart)>3:
18
+ regression = linregress(
19
+ x = chart['Time_ID'],
20
+ y = chart['High'],
21
+ )
22
+ chart = chart.loc[chart['High'] > regression[0] * chart['Time_ID'] + regression[1]]
23
+ return chart
24
+
25
+ # 安値の始点/支点を取得
26
+ def get_lowpoint(start, end):
27
+ chart = df[start:end+1]
28
+ while len(chart)>3:
29
+ regression = linregress(
30
+ x = chart['Time_ID'],
31
+ y = chart['Low'],
32
+ )
33
+ chart = chart.loc[chart['Low'] < regression[0] * chart['Time_ID'] + regression[1]]
34
+ return chart
35
+
36
+ def g_trendlines(span=240, min_interval=3):
37
+ trendlines = []
38
+ slope = [] # 傾き,リスト型
39
+ time = []
40
+
41
+ # 高値の下降トレンドラインを生成
42
+ for i in df.index[::span//2]:
43
+ highpoint = get_highpoint(i, i + span)
44
+ # ポイントが2箇所未満だとエラーになるので回避する
45
+ if len(highpoint) < 2:
46
+ continue
47
+ # 始点と支点が近過ぎたらトレンドラインとして引かない
48
+ if abs(highpoint.index[0] - highpoint.index[1]) < min_interval:
49
+ continue
50
+ regression = linregress(
51
+ x = highpoint['Time_ID'],
52
+ y = highpoint['High'],
53
+ )
54
+ print(regression[0] < 0.0, 'reg_high: ', regression[0], ', ', regression[1], )
55
+
56
+ # 下降してるときだけ
57
+ if regression[0] < 0.0:
58
+ trendlines.append(regression[0] * df['Time_ID'][i:i+span*2] + regression[1])
59
+ slope.append(regression[0] * df['Time_ID'][i:i+span*2])
60
+ time.append(df['Time'][i:i+span*2])
61
+
62
+ # 安値の上昇トレンドラインを生成
63
+ for i in df.index[::span//2]:
64
+ lowpoint = get_lowpoint(i, i + span)
65
+ # ポイントが2箇所未満だとエラーになるので回避する
66
+ if len(lowpoint) < 2:
67
+ continue
68
+ # 始点と支点が近過ぎたらトレンドラインとして引かない
69
+ if abs(lowpoint.index[0] - lowpoint.index[1]) < min_interval:
70
+ continue
71
+ regression = linregress(
72
+ x = lowpoint['Time_ID'],
73
+ y = lowpoint['Low'],
74
+ )
75
+ print(regression[0] > 0.0, 'reg_low: ', regression[0], ', ', regression[1], )
76
+
77
+ # 上昇してるときだけ
78
+ if regression[0] > 0.0:
79
+ trendlines.append(regression[0] * df['Time_ID'][i:i+span*2] + regression[1])
80
+ slope.append(regression[0] * df['Time_ID'][i:i+span*2])
81
+ time.append(df['Time'][i:i+span*2])
82
+
83
+ return trendlines, slope, time
84
+ ```
85
+
86
+ ![イメージ説明](020029d99dc77e7f030d5d91ebd02851.png)
87
+ along_time_dfの中身はこんな感じ
88
+ ```ここに言語を入力
89
+
90
+ #トレンドラインを計算する関数を実行。
91
+ #トレンドラインは同じ時間に複数重なっていることがあるのでdf['Close']に一番近い値を採用する
92
+
93
+
94
+
95
+ #along_time_dfをどうにかしてリストにできれば解決できそう。そのほかの方法はわからない
96
+
97
+
98
+
99
+ zaa, slope, along_time = g_trendlines()
100
+ df_intercept = pd.DataFrame(zaa)
101
+ df_slope = pd.DataFrame(slope)
102
+ along_time_df = pd.DataFrame(along_time)
103
+
104
+ df_intercept = df_intercept.transpose()
105
+ df_slope = df_slope.transpose()
106
+ along_time_df = along_time_df.transpose()
107
+
108
+ df_intercept = df_intercept.astype('float')
109
+ df_slope = df_slope.astype('float')
110
+
111
+ def getNearestValue(minimum, slope_dic):
112
+ """
113
+ 概要: 辞書から0に最も近い値を返却する関数
114
+ @return 0に最も近い値とそれに伴う傾き
115
+ """
116
+
117
+ calc_near_zero = min(minimum.items(), key=lambda x: x[1]) # 0に近い値を求める, the variable is tuple
118
+ key = calc_near_zero[0] #タプルの一つ目の要素を取得 , calc_near_zero = (key, value)
119
+ best_slope = slope_dic[key] # have just a value and トレンドラインの値と同じ列にある傾きを取得している
120
+ best_time = time_dic[key]
121
+ min_diff = calc_near_zero[1] # have just a value and calc_near_zero is tuple
122
+
123
+ return min_diff, best_slope, best_time
124
+
125
+
126
+ #トレードの判断をするときにトレンドラインが複数あると面倒なので一番近いトレンドラインと傾き(上昇or下降)を求めてdfに結合する
127
+ #データフレームのvalueだけをリスト形式で取り出さないとfor文で回せないので変換する
128
+ listdfi = df_intercept.values.tolist()
129
+ listdfs = df_slope.values.tolist()
130
+ listatd = along_time_df.values.tolist() #.values.tolist()これをやると全部NaNになってしまう
131
+ list_df_close = df['Close'][360:].values.tolist()
132
+
133
+ Near_trendline = []
134
+ slope_withTL = []
135
+ time_withtl = []
136
+
137
+ for i, dfi, dfs, atd in zip(list_df_close, listdfi, listdfs, along_time_df):
138
+ minimum = {}
139
+ slope_dic = {}
140
+ time_dic = {}
141
+ for c in range(35):
142
+ if dfi[c]:
143
+ diff = i - dfi[c] # 誤差を求める
144
+ slope = dfs[c] #slopeの値
145
+ tim = atd[c]
146
+ minimum[c] = abs(diff)
147
+ slope_dic[c] = slope
148
+ time_dic[c] = tim
149
+
150
+ best_TL, best_slope, best_time = getNearestValue(minimum, slope_dic)
151
+ Near_trendline.append(best_TL) #一番誤差が少ないdf_interceptの列を採用する
152
+ slope_withTL.append(best_slope)
153
+ time_withtl.append(best_time)
154
+
155
+
156
+ #slopeは上昇トレンドか下降トレンドかだけを知りたいので1,-1に変換する
157
+ slope_withTL = (1 if i >0 else -1 for i in slope_withTL)
158
+
159
+ #Near_trendlineとslope_withTLをデータフレームに変換する
160
+ df2 = pd.DataFrame({'Trend Line': Near_trendline,
161
+ 'Up or Down': slope_withTL,
162
+ 'Time': time_withtl
163
+ })
164
+
165
+
166
+ df3 = pd.merge(df, df2, on='Time', how='left')
167
+ ```
168
+ わかりにくくてすみません。