2016-08-14 8 views
0

では、私はそれで日付を持つデータフレームdfを持っている:パンダ:ループデータフレームを介してカウンタ

df['Survey_Date'].head(4) 
Out[65]: 
0 1990-09-28 
1 1991-07-26 
2 1991-11-23 
3 1992-10-15 

私は別のデータフレームflow_dfを使用して、日付の2の間のメトリックを計算することに興味を持っています。例えば

 date flow 
0 1989-01-01 7480 
1 1989-01-02 5070 
2 1989-01-03 6410 
3 1989-01-04 10900 
4 1989-01-05 11700 

、私はcurrent_dateearly_dateに基づいて別のデータフレームを照会したいと思います:

flow_dfは次のようになります。関心の第1の期間は、次のようになります。

current_date = 1991-07-26 
early_date = 1990-09-28 

私はループの不格好に書かれているし、それは仕事を取得しますが、私はもっとエレガントな方法があると確信しています:

私のアプローチをカウンターでforループ:

def find_peak(early_date,current_date,flow_df): 
    mask = (flow_df['date']>= early_date) & (flow_df['date'] < current_date) 
    query = flow_df.loc[mask] 
    peak_flow = np.max(query['flow'])*0.3048**3 
    return peak_flow 

n=0 
for thing in df['Survey_Date'][1:]: 
    early_date = df['Survey_Date'][n] 
    current_date = thing 
    peak_flow = find_peak(early_date,current_date,flow_df) 
    n+=1 
    df['Avg_Stage'][n] = peak_flow 

カウンタとforループなしでこれを行うにはどうすればよいですか?

所望の出力は次のようになります。あなたはリスト内包にそれを置くことができる。もちろん、

for early_date, current_date in zip(df['Survey_Date'], df['Survey_Date'][1:]): 
    #do whatever yo want. 

:あなたはzip()を使用することができます

Survey_Date Avg_Stage 
0 1990-09-28 
1 1991-07-26 574.831986 
2 1991-11-23 526.693347 
3 1992-10-15 458.732915 
4 1993-04-01 855.168767 
5 1993-11-17 470.059653 
6 1994-04-07 419.089330 
7 1994-10-21 450.237861 
8 1995-04-24 498.376500 
9 1995-06-23 506.871554 
+0

あなたは 'early-date'と' current-date'の間の期間を選択しますか? –

+0

はい、私の質問はどのようにデータフレームを対象の日付でループするかです。 – dubbbdan

+1

あなたのデータフレームには、 'early-date'と' current-date'の間に何もありません。あなたは希望の出力を投稿できますか? –

答えて

2

あなたが定義することができます調査期間を特定して使用する新しい変数を避けるためにforループ。 flow_dfが大きい場合は、はるかに高速になるはずです。

#convert both to datetime, if they are not 
df['Survey_Date'] = pd.to_datetime(df['Survey_Date']) 
flow_df['date'] = pd.to_datetime(flow_df['date']) 

#Merge Survey_Date to flow_df. Most rows of flow_df['Survey_Date'] should be NaT 
flow_df = flow_df.merge(df, left_on='date', right_on='Survey_Date', how='outer') 

# In case not all Survey_Date in flow_df['date'] or data not sorted by date. 
flow_df['date'].fillna(flow_df['Survey_Date'], inplace=True) 
flow_df.sort_values('date', inplace=True) 

#Identify survey period. In your example: [1990-09-28, 1991-07-26) is represented by 0; [1991-07-26, 1991-11-23) = 1; etc. 
flow_df['survey_period'] = flow_df['Survey_Date'].notnull().cumsum() 

#calc Avg_Stage in each survey_period. I did .shift(1) because you want to align period [1990-09-28, 1991-07-26) to 1991-07-26 
df['Avg_Stage'] = (flow_df.groupby('survey_period')['flow'].max()*0.3048**3).shift(1) 
+0

これは私が探していたものです! 'flow_df'はかなり大きく、for文は厄介です。ありがとう! – dubbbdan

0

[some_metric(early_date, current_date) for early_date, current_date in zip(df['Survey_Date'], df['Survey_Date'][1:])] 
+0

ニース、それは私の後ろに近づいています。 – dubbbdan

+1

あなたの質問にもっと正確にする必要がある場合 –

+0

私は単純にforループを使いたくないと言っていたと思っていましたが、詳細については元の投稿を編集しました。 – dubbbdan

関連する問題