2016-04-18 14 views
3

T-SQLのTOP関数と同等のPythonは何ですか?私はトップ50Kの行に自分のデータフレームをフィルタリングするために探しています。私はオンラインで見てきました。私は簡単な例を見つけることができません。パンダ:上位N行、グループあたり上位N行、ROW_NUMBER以上(パーティションBY ... ORDER BY ...)

+0

MaxUは簡単に私に答えを打ち、私よりも良い仕事をしました。将来の参考として、データフレームの索引付けに関する[nice page](http://pandas.pydata.org/pandas-docs/stable/indexing.html)があります。 – Prune

答えて

8

UPDATE: - など、異なるパンダアプローチを示す:を有する基あたり

トップN行

トップN行は、SQL集計関数の等価

オフセット:

ROW_NUMBER()/RANK() OVER(PARTITION BY ... ORDER BY ...)

サンプルDF:

df = pd.DataFrame({ 
    'dep': np.random.choice(list('ABC'), 20), 
    'manager_id': np.random.randint(0, 10, 20), 
    'salary': np.random.randint(5000, 5006, 20) 
}) 

-----------------------オリジナルDF ------------------- -----

In [2]: df 
Out[2]: 
    dep manager_id salary 
0 B   5 5005 
1 A   6 5001 
2 C   8 5000 
3 A   7 5000 
4 B   0 5002 
5 A   3 5003 
6 A   2 5004 
7 A   2 5004 
8 C   3 5002 
9 C   4 5001 
10 A   9 5002 
11 C   9 5000 
12 B   8 5004 
13 A   1 5003 
14 C   7 5005 
15 B   0 5002 
16 B   2 5003 
17 A   4 5000 
18 B   2 5003 
19 B   7 5003 

------------------上位5行(元のインデックス順)----------- --------

In [3]: df.head(5) 
Out[3]: 
    dep manager_id salary 
0 B   5 5005 
1 A   6 5001 
2 C   8 5000 
3 A   7 5000 
4 B   0 5002 

---トップ5行(manager_id DESC、dep ASCでソート)----

In [4]: df.sort_values(by=['manager_id', 'dep'], ascending=[False,True]).head(5) 
Out[4]: 
    dep manager_id salary 
10 A   9 5002 
11 C   9 5000 
12 B   8 5004 
2 C   8 5000 
3 A   7 5000 
SQLの等価 SELECT * FROM tab ORDER BY salary DESC LIMIT 5 OFFSET 3等価

--- ---

In [19]: df.nlargest(5+3, columns=['salary']).tail(5) 
Out[19]: 
    dep manager_id salary 
7 A   2 5004 
12 B   8 5004 
5 A   3 5003 
13 A   1 5003 
16 B   2 5003 

各部門における----トップ2給与(重複なし)-----

---:row_number() over(partition by DEP order by SALARY desc) ---

In [7]: (df.assign(rn=df.sort_values(['salary'], ascending=False) 
    ...:     .groupby(['dep']) 
    ...:     .cumcount() + 1) 
    ...: .query('rn < 3') 
    ...: .sort_values(['dep','rn']) 
    ...:) 
Out[7]: 
    dep manager_id salary rn 
6 A   2 5004 1 
7 A   2 5004 2 
0 B   5 5005 1 
12 B   8 5004 2 
14 C   7 5005 1 
8 C   3 5002 2 

( "nlargest" を使用して)各部門における---トップ2給与----

SQLの等価(重複を有する)各部門における

---第二および第三の各部門の最高給与---

In [16]: (df.assign(rn=df.sort_values(['salary'], ascending=False) 
    ....:     .groupby(['dep']) 
    ....:     .cumcount() + 1) 
    ....: .query('rn >= 2 and rn <= 3') 
    ....: .sort_values(['dep','rn']) 
    ....:) 
Out[16]: 
    dep manager_id salary rn 
7 A   2 5004 2 
13 A   1 5003 3 
12 B   8 5004 2 
18 B   2 5003 3 
8 C   3 5002 2 
9 C   4 5001 3 

---トップ2給与----

--- :rank() over(partition by DEP order by SALARY desc) ---

In [18]: (df.assign(rnk=df.groupby(['dep'])['salary'] 
    ....:     .rank(method='min', ascending=False)) 
    ....: .query('rnk < 3') 
    ....: .sort_values(['dep','rnk']) 
    ....:) 
Out[18]: 
    dep manager_id salary rnk 
6 A   2 5004 1.0 
7 A   2 5004 1.0 
0 B   5 5005 1.0 
12 B   8 5004 2.0 
14 C   7 5005 1.0 
8 C   3 5002 2.0 
+0

もしあなたがdocs http://pandas.pydata.org/pandas-docs/stable/comparison_with_sql.htmlにないもの(または明確ではない)に対するプルリクエストをしたいのなら、それは素晴らしいことです! – Jeff

+0

@ジェフ、試してみるよ。 GitHubに慣れてプルリクエストを行うには時間がかかります – MaxU

+0

これは素晴らしいことですが、MaxUに感謝します。 '重複軸から再インデックスできません'というエラーが表示された場合、インデックスをリセットすることでこれを解決できます:df = df.reset_index() –

関連する問題