2017-11-14 10 views
0

this questionを投稿していて、アプリケーションを拡張する必要があります。私は第二の最大の日付を取得するために必要な場合に予想される出力は次のようになりN最大の日付を取得するパンダ

#import pandas as pd 
#df = pd.read_clipboard() 
#df['Insert_Date'] = pd.to_datetime(df['Insert_Date']) 

# used in example below 
#df2 = df.sort_values(['Vendor','InsertDate']).drop_duplicates(['Vendor'],keep='last') 

Vendor Insert_Date Total 
Steph 2017-10-25 2 
Matt 2017-10-31 13 
Chris 2017-11-03 3 
Steve 2017-10-23 11 
Chris 2017-10-27 3 
Steve 2017-11-01 11 

:私は今、各VendorについてN最大の日付を取得する必要があります

Vendor Insert_Date Total 
Steph 2017-10-25 2 
Steve 2017-10-23 11 
Matt 2017-10-31 13 
Chris 2017-10-27 3 

私は簡単で第二の最大の日付を取得することができます例df.loc[~df.index.isin(df2.index)]df2を使用しますが、私は50番目の最大値を取得する必要がある場合、それは私CLOSを取得し、私もdf.groupby('Vendor')['Insert_Date'].nlargest(N_HERE)を試してみましたisin()を使用するには、データフレームの建物がたくさん...

ですeの場合、ベンダごとにNの値を取得する必要があります。

私はまた、ベンダーによってDFをフィルタリング試してみました:

df.loc[df['Vendor']=='Chris', 'Insert_Date'].nlargest(2)

を私はdf.loc[df['Vendor']=='Chris', 'Insert_Date'].nlargest(2)[2]を有する第2のレコードを取得しようとする場合、それを返します:Timestamp('2017-11-03 00:00:00')を。代わりに私はdf.loc[df['Vendor']=='Chris', 'Insert_Date'].nlargest(2)[1:2]を使用する必要があります。 [2]ではなく、ここでリストスライスを使用する必要がありますか?

要約すれば、ベンダーによってNの最大日付を返すにはどうすればよいですか?

答えて

2

私は最初の問題を誤解している可能性があります。あなたはInsert_Dateでソートし、次に、このようにgroupby + applyを使用することができます:あなたの例のデータについては

n = 9 
df.sort_values('Insert_Date')\ 
      .groupby('Vendor', as_index=False).apply(lambda x: x.iloc[-n]) 

は、n = 0はトリックを行うようです。

df.sort_values('Insert_Date')\ 
     .groupby('Vendor', as_index=False).apply(lambda x: x.iloc[0]) 

    Vendor Insert_Date Total 
0 Chris 2017-10-27  3 
1 Matt 2017-10-31  13 
2 Steph 2017-10-25  2 
3 Steve 2017-10-23  11 

あなたVendorグループがnよりもサイズが小さい場合、このコードは、エラーがスローされます、注意してください。

+0

これはこの小さな例で機能します。しかし、ベンダーごとに10日間の日付があり、9日目の日付を取得する必要がある場合はどうなりますか? – MattR

+0

@MattR自分を説明しましょう。あなたが注文を間違えたと思っていただけで、修正しようとしました。とにかく、私はあなたの最初のステートメントを誤解しているかもしれませんが、私は編集でそれを修正しようとしました。 –

+0

私は同様のものを試しました。 'apply()'で 'iloc'を使うことはできませんでした。もう一度私は車輪を再発明しようとしているように感じ、あなたたちはただちにそれをやります。 – MattR

1

私はheadを使用します(ここではnは2を使用しています)。最後は常にdrop_duplicatesです。

df.sort_values('Insert_Date',ascending=False).groupby('Vendor').\ 
    head(2).drop_duplicates('Vendor',keep='last').sort_index() 
Out[609]: 
    Vendor Insert_Date Total 
0 Steph 2017-10-25  2 
1 Matt 2017-10-31  13 
3 Steve 2017-10-23  11 
4 Chris 2017-10-27  3 
+0

は同じ答えを返します! (私は 'df2'は' df'でなければならないと思いますが?)再びソートマジックを使います。なぜ 'head(N)'がデータフレーム全体を返すのか知っていますか? – MattR

+0

https://github.com/pandas-dev/pandas/blob/v0.21.0/pandas/core/generic.py#L3250-L3265ここで確認できます。基本的には 'head(n)==。iloc [:n、:] '私は' head'を使っています。単に 'apply'を必要としません。 – Wen

+0

コメントに何か不足している可能性があります。 'df.sort_values( 'Insert_Date'、ascending = False).groupby( 'Vendor').head(2)'は、データフレーム全体を返しますか? – MattR

1

私は@ COLDSPEEDの答えがより直接的です。ここでは、nlargestを使用するものがあります。これは、n番目に大きい列を作成する中間ステップを伴います。

n = 2 
df1['nth_largest'] = df1.groupby('Vendor').Insert_Date.transform(lambda x: x.nlargest(n).min()) 
df1.drop_duplicates(subset = ['Vendor', 'nth_largest']).drop('Insert_Date', axis = 1) 


    Vendor Total nth_largest 
0 Steph 2 2017-10-25 
1 Matt 13 2017-10-31 
2 Chris 3 2017-10-27 
3 Steve 11 2017-10-23 
関連する問題