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

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

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

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

pandas

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

Q&A

解決済

2回答

21127閲覧

データフレームの中の一個前の列を参照して、次の列の演算を行う  Python,Pandas

pepasuke623

総合スコア55

Python 3.x

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

pandas

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

0グッド

1クリップ

投稿2017/02/04 16:11

編集2017/02/05 02:56

###前提
いつもお世話になっております。またまたデータフレームの操作方法について質問させていただきます。

下のようなデータフレームがあるとします。

humi temp year 0 98 23 2010 1 89 30 2011 2 85 22 2012 3 97 25 2013 4 84 24 2014 5 85 31 2015 6 88 22 2016
  • humiはその年の湿度の代表値
  • tempはその年の気温の代表値
  • yearは年度

を表しているとします。

###実現したいこと
質問用に無理やり作ったので少し変な問題設定ですが、
0. humi(湿度)が90を超える年はhansode(半袖)が流行る
0. temp(気温)が25を超える年はTanktop(タンクトップ)が流行る
0. humi(湿度)が90以下、かつtemp(気温)が25以下の年は、前の年の流行が継続される(humi(湿度)が90を超える,かつtemp(気温)が25を超える年は無いものとする)

というルールに従い、データフレームに'clothes'の列を追加して、上記の結果を書き込みます。
出力結果としては次のようになるはずです。

humi temp year clothes 0 98 23 2010 hansode 1 89 30 2011 Tanktop 2 85 22 2012 Tanktop 3 97 25 2013 hansode 4 84 24 2014 hansode 5 85 31 2015 Tanktop 6 88 22 2016 Tanktop

###試したこと
applyとかmapなどを使ってなんとか出来ないものかと試みましたが、「前の年の流行が継続される」という部分が出来ませんでした。
Forループを使って無理やり書けばこんな感じです。

Python

1import pandas as pd 2 3# データフレームの定義 4df = pd.DataFrame( 5 {'year': [2010, 2011, 2012, 2013, 2014, 2015, 2016], 6 'humi': [98, 89, 85, 97, 84, 85, 88], 7 'temp': [23, 30, 22, 25, 24, 31, 22]}) 8 9# 空のデータフレームを作る 10df_e = pd.DataFrame(index=range(len(df)), columns=['clothes']) 11 12# Forループで判定 13for i in range(len(df)): 14 if df.ix[i,'humi'] > 90: 15 df_e.ix[i,'clothes'] = 'hansode' 16 elif i > 0 and df.ix[i,'temp'] > 25: 17 df_e.ix[i,'clothes'] = 'Tanktop' 18 else: 19 df_e.ix[i,'clothes'] = 1 20 21# 無理やりくっつける 22df = pd.concat([df,df_e],axis=1) 23 24 # 「1」を置き換える 25for i in range(len(df)): 26 if i > 0 and df.ix[i,'clothes'] == 1: 27 df.ix[i,'clothes'] = df.ix[i-1,'clothes'] 28 29print(df)

別に好んでForループを使っているわけではなく、なるべく短く簡潔に、かつ高速に動くものを作りたいと思っています。
うまい方法があれば教えていただければと思います。

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

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

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

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

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

guest

回答2

0

ベストアンサー

applyではその行だけで判定可能な値('hansode' or 'Tanktop')を設定し、
その他の場合は None を設定しておきます。
その結果に対して、fillnaの method 引数に'ffill'を指定すると、
Noneを直前の有効値で置き換えることができます。

Python

1df['clothes'] = df.apply(lambda s: 'hansode' if s.humi > 90 else 'Tanktop' if s.temp > 25 else None, axis=1).fillna(method='ffill')

投稿2017/02/05 06:31

copepoda

総合スコア324

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

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

0

それぞれの判別する処理を関数にしてapplyしてみました。
前年のデータがなかった場合等の例外処理はしておりませんので、適宜修正してください。

python

1# 半袖かタンクトップを返す 2def get_clothes(humi, temp): 3 if humi > 90: 4 return 'hansode' 5 if temp > 25: 6 return 'Tanktop' 7 8 9# 前年のclothe列を返す 10def get_prev_clothes(year): 11 return df.loc[df['year'] == year - 1, 'clothes'].values[0] 12 13 14df['clothes'] = df.apply(lambda x: get_clothes(x['humi'], x['temp']), axis=1) 15 16# 上記で判定できなかったデータを処理 17prev_clothes = df.loc[df['clothes'].isnull(), 'year'].map(get_prev_clothes) 18df.loc[prev_clothes.index, 'clothes'] = prev_clothes

投稿2017/02/05 04:34

driller

総合スコア720

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.37%

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

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

質問する

関連した質問