pandas相似SQL的數據查詢

在python中可使用pandas包來進行相似SQL的數據查詢,這篇文章就給出一些用pandas去作相似SQL的操做的例子。首先導入numpy和pandas包。python

import numpy as np
import pandas as pd
1
2
本文使用tips數據集用來說解相似SQL操做的例子,首先導入以DataFrame的形式的tips數據集git

url = 'https://raw.github.com/pandas-dev/pandas/master/pandas/tests/data/tips.csv'
tips = pd.read_csv(url)
1
2
可使用head()來展現數據集中的前5列數據github

tips.head()
print(tips.head())
1
2
能夠獲得以下結果:

這裏就取出了tips數據集中的前五行數據。
一樣可使用tail()來展現數據集中的後面5列數據url

tips.tail()
print(tips.tail())
1
2
運行結果以下:

下面舉例說明幾種常見的SQL操做以及相對應的pandas中的操做。
(1)pandas的select操做:在SQL中,若是咱們要從tips中選取前五行total_bill, tip, smoker和time幾列數據,SQL的語法爲:.net

select total_bill, tip, smoker, time
from tips
limit 5
1
2
3
在pandas操做中,這幾列數據能夠經過在DataFrame中寫出要選取的列,語法以下:blog

tips[['total_bill', 'tip', 'smoker', 'time']].head(5)
print(tips[['total_bill', 'tip', 'smoker', 'time']].head(5))
1
2
運行結果以下:

若是要選取全部的列,就不須要在DataFrame中填寫參數,就像SQL的select *操做
2)pandas中的where操做:在SQL中,where操做語法爲:索引

select * from tips where time = 'dinner' limit 5
1
pandas語法以下:ip

tips[tips['time'] == 'Dinner'].head(5)
print(tips[tips['time'] == 'Dinner'].head(5))
1
2
運行結果以下:

若是咱們想知道tips數據集中有多少條數據是符合咱們所要查找數據要求的,能夠用以下操做:ci

is_dinner = tips['time'] == 'Dinner'
is_dinner.value_counts()
1
2
運行結果以下:
True 176
False 68
Name: time, dtype: int64
從輸出結果中能夠看出有176條數據知足time是Dinner的條件,有68條數據不知足該條件
select操做也能夠寫爲:pandas

tips[is_dinner].head()
1
(3) pandas中的and和or操做:如今若是要查找time爲Dinner而且tip大於5的數據,SQL語法爲:

select * from tips where time = 'Dinner' and tip > 5
1
在pandas中的相對應的語法爲:

tips[(tips['time'] == 'Dinner') & (tips['tip'] > 5)]
1
or能夠在pandas對應爲|,例子以下:

tips[(tips['time'] == 'Dinner') | (tips['tip'] > 5)]
1
(4)查找空值:pandas中查找是否爲空值能夠用 notna()和isna() ,frame數據集以下

frame = pd.DataFrame({'col1': ['A', 'B', np.NaN, 'C', 'D'], 'col2': ['F', np.NaN, 'G', 'H', 'I']})
1
若是要在數據集中的知足col2爲空的數據,SQL語法爲:

select * frame where col2 is null
1
對應的pandas語法爲:

frame[frame['col2'].isna()]
1
(5)group by操做:在pandas中能夠用groupby()方法來實現group by操做
例如,以性別來分組查找各分組的數量,SQL語法爲:

select sex, count(*) from tips group by sex
1
對應的pandas語法爲:

tips.groupby('sex').size()
1
運行結果以下:
sex
Female 87
Male 157
dtype: int64
這裏面咱們使用size()方法來計數而沒有使用count()方法,由於size()方法會返回全部的數量,而count()方法的返回值爲每個列的不爲空的數量

tips.groupby('sex').count()
1
運行結果以下:
total_bill tip smoker day time size
sex
Female 87 87 87 87 87 87
Male 157 157 157 157 157 157
可使用count()方法來計算某一列的數量,例子以下:

tips.groupby('sex')['total_bill'].count()
1
運行結果以下:
sex
Female 87
Male 157
Name: total_bill, dtype: int64
以day來分組,計算tip的數量和平均值,SQL能夠寫爲:

select day, avg(tip), count(*) from tips group by day
1
對應的pandas可使用agg()方法來實現多種多個方法,語法以下:

tips.groupby('day').agg({'tip': np.mean, 'day': np.size})
1
運行結果以下:
day tip
day
Fri 19 2.734737
Sat 87 2.993103
Sun 76 3.255132
Thur 62 2.771452
要實現多個屬性的分組,SQL能夠寫爲:

select smoker, day, avg(tip), count(*) from tips group by smoker, day
1
pandas中能夠寫爲:

tips.groupby(['smoker', 'day']).agg({'tip': [np.size, np.mean]})
1
運行結果以下:
tip
size mean
smoker day
No Fri 4.0 2.812500
Sat 45.0 3.102889
Sun 57.0 3.167895
Thur 45.0 2.673778
Yes Fri 15.0 2.714000
Sat 42.0 2.875476
Sun 19.0 3.516842
Thur 17.0 3.030000
(6)join操做:在pandas中join操做能夠經過join()或merge()方法來實現,默認的join()方法會根據索引進行聯結。
inner join,SQL語法以下:

select * from df1 inner join df2 on df1.key = df2.key
1
對應的pandas操做以下:

pd.merge(df1, df2, on='key')
1
運行結果以下:
key value_x value_y
0 B 0.562542 0.799541
1 D 0.757426 0.687838
2 D 0.757426 0.746944
merge()方法也能夠用來用一個Dataframe的索引join另外一個Dataframe的列

indexed_df2 = df2.set_index('key')
pd.merge(df1, indexed_df2, left_on='key', right_index=True)
1
2
left outer join,展現全部的df1,SQL操做以下:

select * from df1 left outer join df2 on df1.key = df2.key
1
對應的pandas操做爲:

pd.merge(df1, df2, on='key', how='left')
1
運行結果以下:
key value_x value_y
0 A 0.198997 NaN
1 B 0.562542 0.799541
2 C 0.125744 NaN
3 D 0.757426 0.687838
4 D 0.757426 0.746944
right outer join,展現全部的df2,SQL操做以下:

select * from df1 right outer join df2 on df1.key = df2.key
1
對應的pandas操做爲:

pd.merge(df1, df2, on='key', how='right')
1
運行結果以下:
key value_x value_y
0 B 0.562542 0.799541
1 D 0.757426 0.687838
2 D 0.757426 0.746944
full join,展現全部的df1,df2數據,SQL操做以下:

select * from df1 full outer join de2 on df1.key = df2.key
1
對應的pandas操做爲:

pd.merge(df1, df2, on='key', how='outer')
1
運行結果以下:
key value_x value_y
0 A 0.198997 NaN
1 B 0.562542 0.799541
2 C 0.125744 NaN
3 D 0.757426 0.687838
4 D 0.757426 0.746944
5 E NaN 0.169292
(7)union操做,在pandas中union all的操做能夠經過concat()方法來完成

df1 = pd.DataFrame({'city': ['Chicago', 'San Francisco', 'New York City'], 'rank': range(1, 4)})
df2 = pd.DataFrame({'city': ['Chicago', 'Boston', 'Los Angeles'], 'rank': [1, 4, 5]})
1
2
SQL操做以下

select * from df1 union all select * from df2
1
pandas對應操做以下:

pd.concat([df1, df2])
1
SQL中union與union all的區別爲union會去除重複,在pandas中能夠用drop_duplicates()來去除重複

pd.concat([df1, df2]).drop_duplicates()
1
key value
0 A 0.198997
1 B 0.562542
2 C 0.125744
3 D 0.757426
0 B 0.799541
1 D 0.687838
2 D 0.746944
3 E 0.169292
(8)有偏移的前N行數據

SELECT * FROM tips
ORDER BY tip DESC
LIMIT 10 OFFSET 5;
1
2
3
tips.nlargest(10+5, columns='tip').tail(10)
1
運行結果以下:
total_bill tip sex smoker day time size
183 23.17 6.50 Male Yes Sun Dinner 4
214 28.17 6.50 Female Yes Sat Dinner 3
47 32.40 6.00 Male No Sun Dinner 4
239 29.03 5.92 Male No Sat Dinner 3
88 24.71 5.85 Male No Thur Lunch 2
181 23.33 5.65 Male Yes Sun Dinner 2
44 30.40 5.60 Male No Sun Dinner 4
52 34.81 5.20 Female No Sun Dinner 4
85 34.83 5.17 Female No Thur Lunch 4
211 25.89 5.16 Male Yes Sat Dinner 4
(9) 每一組的第N行

SELECT * FROM (
SELECT
t.*,
ROW_NUMBER() OVER(PARTITION BY day ORDER BY total_bill DESC) AS rn
FROM tips t
)
WHERE rn < 3
ORDER BY day, rn;
1
2
3
4
5
6
7
8
(tips.assign(rn=tips.sort_values(['total_bill'], ascending=False).groupby(['day']).cumcount()+1).query('rn < 3').sort_values(['day', 'rn'])
)
1
2
運行結果以下:
total_bill tip sex smoker day time size rn
95 40.17 4.73 Male Yes Fri Dinner 4 1
90 28.97 3.00 Male Yes Fri Dinner 2 2
170 50.81 10.00 Male Yes Sat Dinner 3 1
212 48.33 9.00 Male No Sat Dinner 4 2
156 48.17 5.00 Male No Sun Dinner 6 1
182 45.35 3.50 Male Yes Sun Dinner 3 2
197 43.11 5.00 Female Yes Thur Lunch 4 1
142 41.19 5.00 Male No Thur Lunch 5 2
使用rank()方法一樣能達到相同的效果

SELECT * FROM (
SELECT
t.*,
RANK() OVER(PARTITION BY sex ORDER BY tip) AS rnk
FROM tips t
WHERE tip < 2
)
WHERE rnk < 3
ORDER BY sex, rnk;
1
2
3
4
5
6
7
8
9
tips.assign(rnk=tips.groupby(['day'])['total_bill'].rank(method='first', ascending=False)).query('rnk < 3').sort_values(['day', 'rnk'])
)
1
2
(10)update 方法

UPDATE tips
SET tip = tip*2
WHERE tip < 2;
1
2
3
tips.loc[tips['tip'] < 2, 'tip'] *= 2
1
(11)delete方法

DELETE FROM tips
WHERE tip > 9;
1
2
在pandas中,咱們須要選擇留下來的列而不是去刪除不須要的列

tips = tips.loc[tips['tip'] <= 9] ———————————————— 版權聲明:本文爲CSDN博主「詩蕊」的原創文章,遵循CC 4.0 by-sa版權協議,轉載請附上原文出處連接及本聲明。原文連接:https://blog.csdn.net/katherine_hsr/article/details/79054404

相關文章
相關標籤/搜索