- 什么是Pandas
- 一、如何讀取數據庫-read_sql
- 二、如何篩選數據
- 三、如何連表-merge
- 四、如何刪除一行或一列-drop
- 五、如何分組統計-groupyby
- 六、如何排序-sort_values/sort_index
- 七、如何重建索引-groupby(as_index=False)/reset_index
- 八、如何翻轉dataframe-T
- 九、如何重命名列-rename
- 十、如何強制轉換類型-astype
- 十一、如何在只有一列的情況下groupby並count-size
- 十二、如何操作時間-.dt.
- 十三、如何操作字符串-.str.
- 十四、如何進行數據透視-pivot/pivot_table
- 十五、如何進行可視化-plot
- 十六、如何應用函數和映射
- 十七、如何處理缺失數據
- 十八、如何使用多級索引
- 十九、如何刪除重復數據-drop_duplicated
- 二十、如何替換值-replace
- 二十一、如何連接兩個dataframe-concat
- 二十二、如何重新設置索引-reindex
- 二十二、如何重新采樣-resample
- 二十三、如何打補丁-combine_first
- 二十四、如何進行排名-rank
- 二十五、如何應用函數修改原dataframe-指定參數inplace
什么是Pandas
Pandas 是基於NumPy 的一種工具,該工具是為了解決數據分析任務而創建的。
Pandas納入了大量庫和一些標准的數據模型,提供了大量能使我們快速便捷地處理數據的函數和方法。
主要包含兩種數據類型:Series和DataFrame
- Series可以理解為dict的升級版本,主數組存放numpy數據類型,index數據存放索引
- DataFrame相當於多維的Series,有兩個索引數組,分別是行索引和列索引,可以理解成Series組成的字典
相關幫助文檔
一、如何讀取數據庫-read_sql
示例代碼如下
from sqlalchemy import create_engine
import pandas as pd
username = '用戶名'
password = '密碼'
host = '連接地址'
db = '數據庫'
port = 端口號
link = f'''mysql+pymysql://{username}:{password}@{host}:{port}/{db}?charset=utf8'''
engine = create_engine(link, pool_recycle=3600)
核心方法read_sql
log:pd.DataFrame = pd.read_sql("SELECT * FROM log ORDER BY id DESC ",engine)
執行結果如下

二、如何篩選數據
- 篩選創建時間大於某個時間點的記錄
import datetime
log[log['create_time'] > '2020-01-15 16:14:22']

- 篩選指定列的DataFrame
直接傳遞數組給給DataFrame
logs[['user_id','type']]

- 獲取一列Series
logs['type']

- iloc和loc
iloc[行,列]是根據行號和列號獲取,loc[行索引 ,列索引]是根據索引名獲取

三、如何連表-merge
現在我需要將user_id對應的用戶名找出來,示例代碼如下
#查詢出所有的用戶,以便將log和users做join
users:pd.DataFrame=pd.read_sql("SELECT * FROM users",engine)
users

*
users和log的字段太多,先做一下篩選
log=log[['type','user_id','project_id','create_time']]
users=users[['id','username','real_name']]
執行join,使用merge方法,how指定左連,left_on指定左表使用的字段, right_on指定右表使用的字段
log.merge(users,how='left',left_on='user_id',right_on='id')

四、如何刪除一行或一列-drop
drop方法,axis為0代表行,1代表列
renameRes.drop('創建時間',axis=1)
五、如何分組統計-groupyby
dropRes.groupby(['type','real_name']).count()
groupby也可以可以傳入一個能夠訪問索引上字段的函數
rng=pd.date_range('1/1/2020',periods=100,freq='D')
ts=pd.Series(np.random.randn(len(rng)),index=rng)
ts.groupby(lambda x:x.month).mean()
2020-01-31 0.182420
2020-02-29 0.200134
2020-03-31 -0.108818
2020-04-30 -0.187426
Freq: M, dtype: float64
六、如何排序-sort_values/sort_index
by指定字段,ascending指定升序還是降序
log.sort_values(by='user_id',ascending=False)

七、如何重建索引-groupby(as_index=False)/reset_index
默認groupby后的結果是行索引是groupby的字段
log.merge(users,how='left',left_on='user_id',right_on='id').groupby('type').count()

groupby指定參數as_index
log.merge(users,how='left',left_on='user_id',right_on='id').groupby('type',as_index=False).count()

另外,還可以count完后直接調用reset_index方法
log.merge(users,how='left',left_on='user_id',right_on='id').groupby('type').count().reset_index()

八、如何翻轉dataframe-T
log.T

九、如何重命名列-rename
使用rename方法,傳遞一個字典即可,如下
pd.DataFrame = res[['type','username','real_name','create_time']].rename({'create_time':'創建時間'},axis=1)
十、如何強制轉換類型-astype
log['create_time'].astype(str)
十一、如何在只有一列的情況下groupby並count-size
count是必須依賴其他列做統計的,當只有一列的時候如何還使用count,是看不出統計字段的,正確的方法應該是使用size
test4=pd.read_sql("SELECT `type` FROM log LIMIT 100",engine)
test4.groupby('type').size()

十二、如何操作時間-.dt.
例如,要將create_time轉為YY-MM-DD格式,可以使用函數.dt.date
log['create_time'].dt.date

具體方法可以參考Series的API文檔的Datetime操作
十三、如何操作字符串-.str.
例如,轉為大寫
log['type'].str.upper()

具體方法可以參考Series的API文檔的字符串操作
十四、如何進行數據透視-pivot/pivot_table
簡單的理解就是一個更高級的groupby功能
df = pd.DataFrame({'foo': ['one', 'one', 'one', 'two', 'two',
'two'],
'bar': ['A', 'B', 'C', 'A', 'B', 'C'],
'baz': [1, 2, 3, 4, 5, 6],
'zoo': ['x', 'y', 'z', 'q', 'w', 't']})
df.pivot(index='foo', columns='bar', values='baz')

pivot_table支持分組后再聚合操作
df = pd.DataFrame({"A": ["foo", "foo", "foo", "foo", "foo",
"bar", "bar", "bar", "bar"],
"B": ["one", "one", "one", "two", "two",
"one", "one", "two", "two"],
"C": ["small", "large", "large", "small",
"small", "large", "small", "small",
"large"],
"D": [1, 2, 2, 3, 3, 4, 5, 6, 7],
"E": [2, 4, 5, 5, 6, 6, 8, 9, 9]}
)

根據ABC分組,計算D的值,AB為行索引,C為列索引再使用sum函數,如下
df.pivot_table(values='D', index=['A', 'B'], columns=['C'], aggfunc=np.sum, fill_value=0)

十五、如何進行可視化-plot
一般使用matplotlib進行繪圖
例如,統計所有的操作日志最多的前10個繪制直方圖
先取出這些數據,如下
#獲取所有操作類型最多的10條數據
countRes=log.groupby('type',as_index=False).count().drop(['create_time','project_id'],axis=1).rename({'user_id':'count'},axis=1).sort_values(by='count',ascending=False).head(10)

為了讓圖是遞增的狀態,我們反轉一下
countRes=countRes.iloc[::-1]
再使用matplotlib繪制直方圖
import matplotlib.pyplot as plt
plt.barh(countRes['type'],countRes['count'])

十六、如何應用函數和映射
-
apply(DataFrame)
DataFrame的函數,apply將函數應用到由各列或行所形成的一維數組上,默認是傳入列的Series,可以指定axis=1傳入行

-
applymap(DataFrame)
DataFrame的函數,對每個元素應用函數

-
map/apply(Series)
對應Dataframe的applymap

十七、如何處理缺失數據
pands使用NaN(Not a Number)表示缺失數據,處理方法有
- dropna:對軸標簽進行過濾
- fillna:用指定值或插值方法(如ffill或bfill)填充缺失數據
- isnull:返回一個含有布爾值的對象
- notnull:isnull的否定形式
十八、如何使用多級索引
- Series多級索引
data = pd.Series(np.random.randn(10),
index=[
['a','a','a','b','b','b','c','c','d','d'],
[1, 2, 3, 1, 2, 3, 1, 2, 2, 3]
]
)

選取一個子集
data['b']
選取多個子集
data['b':'c']
選取內層:,號后面添加行號
data[:,2]

- Series和DataFrame互轉
#Series轉換為DataFrame
data.unstack()
#將DataFrame轉換為一個Series
data.unstack().stack()

- DataFrame的多級索引
frame=pd.DataFrame(np.arange(12).reshape((4,3)),
index=[
['a','a','b','b'],
[1,2,1,2]
],
columns=[
['Ohio','Ohio','Colorado'],
['Green','Red','Green']
],
)
- 給索引命名
frame.index.names=['key1','key2']
frame.columns.names=['state','color']

- swaplevel:重排分級順序,互換級別的對象
frame.swaplevel('key1','key2')

- sort_index:根據單個級別中的值對數據進行反序
frame.sort_index(level=0,ascending=False)

- set_index:將其一個或多個列轉換為行索引,並創建一個新的DataFrame
df=pd.DataFrame({
'a':range(7),
'b':range(7,0,-1),
'c':['one','one','one','two','two','two','two'],
'd':[0,1,2,0,1,2,3]
})
df.set_index(['c','d'])

- reset_index:功能和set_index相反,層次化索引的級別會被轉移到列里面

十九、如何刪除重復數據-drop_duplicated
data=pd.DataFrame({
'k1':['one']*3 + ['two']*4,
'kw':[1,1,2,3,3,4,4]
})

data.drop_duplicates()

二十、如何替換值-replace
df = pd.DataFrame({'foo': ['one', 'one', 'one', 'two', 'two',
'two'],
'bar': ['A', 'B', 'C', 'A', 'B', 'C'],
'baz': [1, 2, 3, 4, 5, 6],
'zoo': ['x', 'y', 'z', 'q', 'w', 't']})

替換A和B為chenqionghe,第一個參數為查找值,第二個參數為替換的值
df.replace(['A','B'],'chenqionghe')

也可以傳入字典,替換多個值
df.replace({'A':'cqh','B':'chenqionghe'})

二十一、如何連接兩個dataframe-concat
df1=DataFrame(np.arange(6).reshape(3,2),
index=list('abc'),
columns=['one','two']
)
df2=DataFrame(5+np.arange(4).reshape(2,2),
index=list('ac'),
columns=['three','four']
)

列拼接
pd.concat([df1,df2],sort=False)

行拼接
pd.concat([df1,df2],axis=1,sort=False)

二十二、如何重新設置索引-reindex
frame=pd.DataFrame(np.arange(9).reshape((3,3)),
index=['a','b','c'],
columns=['light','weight','baby']
)
#默認修改行索引
frame2=frame.reindex(['a','b','c','d'])
#同時修改行索引和列索引
frame.reindex(index=['a','b','c','d'],columns=['light','gym','muscle'])

二十二、如何重新采樣-resample
創建3個周三的時間序列
ts1=pd.Series(
np.random.randn(3),
index=pd.date_range('2020-6-13',periods=3,freq='W-WED')
)

升采樣轉為每個工作日
ts1.resample('B').asfreq()

指定為ffill的填充
ts1.resample('B').ffill()

二十三、如何打補丁-combine_first
combine_first相當於用參數對象中的數據為調用者對象的缺失數據”打補丁“
df1=pd.DataFrame({
'a':[1,np.nan,5,np.nan],
'b':[np.nan,2,np.nan,6],
'c':range(2,18,4)
})
df2=pd.DataFrame({
'a':[5,4,np.nan,3,7],
'b':['chenqionghe',3,4,6,8]
})

然后我們可以用df2的值給d1打補丁,如下
df1.combine_first(df2)

二十四、如何進行排名-rank
a=pd.DataFrame(np.arange(60).reshape(10,6),columns=['a','b','c','d','e','f'])
默認是對行進行排序,如下
a.rank()

可以傳axis=1對列進行排序
a.rank(axis=1)

默認是升序,可以傳入ascending=False進行降序
a.rank(ascending=False)

二十五、如何應用函數修改原dataframe-指定參數inplace
pandas 中 inplace 參數在很多函數中都會有,它的作用是:是否在原對象基礎上進行修改
- inplace = True:不創建新的對象,直接對原始對象進行修改;
- inplace = False:對數據進行修改,創建並返回新的對象承載其修改結果。
默認是False,即創建新的對象進行修改,原對象不變,和深復制和淺復制有些類似。
