相当于熊猫中SQL的LIMIT和OFFSET?

时间:2018-12-26 16:17:41

标签: python pandas

我有一个这样的数据框:

   id type city
0   2    d    H
1   7    c    J
2   7    x    Y
3   2    o    G
4   6    i    F
5   5    b    E
6   6    v    G
7   8    u    L
8   1    g    L
9   8    k    U

我希望使用pandas获得与SQL命令类似的输出:

select id,type
from df
order by type desc
limit 4
offset 2

所需的结果是:

   id type
0   8    u
1   2    o
2   8    k
3   6    i

我尝试遵循官方教程https://pandas.pydata.org/pandas-docs/stable/comparison_with_sql.html#top-n-rows-with-offset

df.nlargest(4+2, columns='type').tail(4)

但是,这失败了。

如何解决问题?

更新

import numpy as np
import pandas as pd
import pandasql as pdsql
from pandasql import sqldf
pysqldf = lambda q: sqldf(q, globals())
df = pd.read_csv('http://ourairports.com/data/airports.csv')


q = '''
select id,type
from df
order by type desc
limit 4
offset 2
'''

print(pysqldf(q))

```
       id           type
0    6525  small_airport
1  322127  small_airport
2    6527  small_airport
3    6528  small_airport
```

使用熊猫:

print(df.sort_values('type', ascending=False).iloc[2:2+4][['id','type']])
           id           type
43740   37023  small_airport
43739   37022  small_airport
24046  308281  small_airport
24047  309587  small_airport

2 个答案:

答案 0 :(得分:2)

是的,整数位置,其中iloc的起始索引是“偏移”,结束索引以“限制”递增:

df.sort_values('type', ascending=False).iloc[2:6]

输出:

   id type city
7   8    u    L
3   2    o    G
9   8    k    U
4   6    i    F

您可以添加reset_index来清理索引。

print(df.sort_values('type', ascending=False).iloc[2:6].reset_index(drop=True))

输出:

   id type city
0   8    u    L
1   2    o    G
2   8    k    U
3   6    i    F

更新让我们按类型和索引进行排序:

df.index.name = 'index'
df[['id','type']].sort_values(['type','index'], ascending=[False,True]).iloc[2:6]

输出:

   index      id           type
0      3    6525  small_airport
1      5  322127  small_airport
2      6    6527  small_airport
3      7    6528  small_airport

答案 1 :(得分:2)

您可以将sort_valuesascending=False一起使用,并使用.loc()用感兴趣的行和列对结果进行切片(已重置索引):

offset = 2
limit = 4
(df.sort_values(by='type', ascending=False).reset_index(drop=True)
               .loc[offset : offset+limit-1, ['id','type']])

   id type
2   8    u
3   2    o
4   8    k
5   6    i