質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

Q&A

1回答

4336閲覧

Pandasでapply、lambdaを使って条件判断をしたい

uraco

総合スコア15

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

0グッド

0クリップ

投稿2018/08/31 05:05

Pandasの時系列データのDataFrameにある'value'というカラムで、
その時点から以降の'value'を見て、先に+0.3になれば'up'、−0.3になれば'down'という判定をして、
その結果を新しいカラムに格納したいと思っています。

一応以下のコードでできてはいるのですが、データが大きくなると動かなくなってしまいました。
なのでこれを関数にしてapplyとlambdaで追加しようとしたのですが、失敗しました。(下方の失敗コード)
このあたりの理解が不足していることだけはわかったのですが・・・。

どのように修正すればうまくできますか?
もしくは考え方が違うのかな?とも感じています。

いずれにしてもアドバイスが欲しいので、ヒント(もちろん答えも歓迎)や役立つ解説サイトの紹介など・・・どうぞよろしくお願いいたします!!

●一応動くコード

python

1import pandas as pd 2import numpy as np 3 4check = [] 5for i in range(len(datas['value'])-1): 6 for j in np.arange(i+1,len(datas['value'])): 7 f = datas['value'][j] - datas['value'][i] 8 if f >= 0.3: 9 result = 'up' 10 elif f <= -0.3: 11 result = 'down' 12 else: 13 result = '-' 14 check.append(result) 15check.append('-') 16 17datas['check'] = check 18

●失敗したコード

python

1def func_check(s): 2 for i in range(len(s)-1): 3 for j in np.arange(i+1,len(s)): 4 f = s[j] - s[i] 5 if f >= 0.3: 6 result = 'up' 7 elif f <= -0.3: 8 result = 'down' 9 else: 10 result = '-' 11 return result 12 13 14datas['value'].apply(lambda x: func_check(x)) 15

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

apply lambdaは、DataFrameの列の中の一個一個に対して指定の処理をしていくものになります
例えば、datas['value']が[1,2,3]のようになっていた場合、

datas['value'].apply(lambda x: func_check(x))

のxにはlist[1,2,3]が入っているのではなく、その中の要素1や2や3が入ります。
func_check(s)中でprint(s)を実行してみて、sの中身を確認してみてください。

あと、「一応動くコード」の処理だと、

j in np.arange(i+1,len(datas['value'])):

の内でresultが更新されていって、結局i版目と一番最後の値との差からup、downを判定するコードになっている気がします。

上手い書き方ではないですが、以下の書き方でどうでしょう?
一部行列演算に変わっているため、動くようになっていることを期待します。

python

1import pandas as pd 2 3df = pd.DataFrame({ 4 'value': [0.1,0.6,0.2,-0.1,0.0] 5}) 6 7def func_check(x): 8 if x >= 0.3: 9 return 'up' 10 if x <= -0.3: 11 return 'down' 12 return None 13 14l = [] 15for i, v in enumerate(df.value.values[:-1]): 16 checked_list = (df[i+1:].value - v).apply(lambda x: func_check(x)) #以降のup downを判定 17 checked_list_droped = checked_list.dropna() # Noneを削除 18 if len(checked_list_droped) == 0: # 以降の値が全部Noneだった時 19 l.append('-') 20 else: 21 l.append(checked_list_droped.values[0]) # 一番最初のup or downを取り出して格納 22l.append('-') 23df['checked'] = l

投稿2019/05/25 09:29

haritoshi

総合スコア79

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問