你們好,今天想和你們分享一下有關pandas的學習新的,我因工做須要,從去年12月開始接觸這個很是好用的包,到如今爲止也是算是熟悉了一些,所以發現了它的強大之處,特地想要和朋友們分享,特別是若是你天天和excel打交道,老是須要編寫一些vba函數或者對行列進行groupby啊,merge,join啊之類的,相信我,pandas會讓你解脫的。html
好啦,閒話少說,這篇文章的基礎是假設你已經大概據說過了pandas的一些概念和用途,若是還大致上不太清楚的朋友們,能夠去百度一下相關基礎介紹,本分主要分紅四個部分:python
首先,讓咱們明確一點,pandas這個包是在numpy的基礎上獲得的,所以可能有的朋友會有疑問,要不要先學學numpy,個人我的建議是真的不太須要,由於大多數的狀況下基本用不到,固然,若是你處理的是科學實驗類型的數據的話,當我沒說,我這裏的應用場景主要是通常類型的常見數據,好比:mysql
這種狀況下,學習pandas會很是有用,這裏咱們說的數據都是二維的table,在pandas中也稱做dataframe。 pandas中其實一共有三種類型的常見數據:git
數據結構 | 維度 | 說明 |
---|---|---|
Series | 1 | 相似list,一維數組 |
Data Frames | 2 | 最多見的二維數據結構,excel,sql的表就是這個 |
Panel | 3 | 用的不多,三維結構 |
pandas主要包括三類數據結構,分別是:github
Series:一維數組,與Numpy中的一維array相似。兩者與Python基本的數據結構List也很相近,其區別是:List中的元素能夠是不一樣的數據類型,而Array和Series中則只容許存儲相同的數據類型,這樣能夠更有效的使用內存,提升運算效率。sql
DataFrame:二維的表格型數據結構。不少功能與R中的data.frame相似。能夠將DataFrame理解爲Series的容器。如下的內容主要以DataFrame爲主。json
Panel :三維的數組,能夠理解爲DataFrame的容器。api
Pandas官網,更多功能請參考 pandas-docs.github.io/pandas-docs…數組
這裏咱們主要聚焦在Dataframe上,一個dataframe長的基本上以下這番模樣:bash
Name | Age | Mark |
---|---|---|
John | 15 | 78 |
Mike | 23 | 86 |
Mary | 36 | 95 |
咱們把這個簡單的dataframe起個名字叫df,那麼它包括的最基礎的元素有:
Dataframe 是應用最多也是最普遍的數據結構,如今就讓咱們開始學習建立一個dataframe吧~ ###1.1 建立Dataframe###
建立一個Dataframe的方法有不少,整體上來講最多見的有及種:
真實場景中大多數都是從其餘數據源讀取,咱們會在第3部分講到
建立空dataframe
這個很是簡單:
import pandas as pd
# Calling DataFrame constructor
df = pd.DataFrame()
print(df)
Out:Empty DataFrame
Columns: []
Index: []
複製代碼
利用dict建立(1)
import pandas as pd
print (f" Using {pd.__name__},Version {pd.__version__}")
Out: Using pandas , version 0.23.4
複製代碼
首先要import pandas 包,這裏縮寫爲pd,如今讓咱們從dict建立一個dataframe:
>>> dict = {'name':["Tom", "Bob", "Mary", "James"],
'age': [18, 30, 25, 40],
'city':["Beijing", "ShangHai","GuangZhou", "ShenZhen"]}
>>> df = pd.DataFrame(dict)
>>> df
複製代碼
建立結果以下:
age | city | name | |
---|---|---|---|
0 | 18 | Beijing | Tom |
1 | 30 | ShangHai | Bob |
2 | 25 | GuangZhou | Mary |
3 | 40 | ShenZhen | James |
很簡單是否是,你們可能發現了,最左邊的東西就是index ,0,1,2,3,若是咱們不指定會自動生成從0默認開始的序列,一直到你的dataframe的最後一行,相似於excel左邊的編號
利用dict建立(2)
此次讓咱們建立的更加規範一些:
index = pd.Index(["Tom", "Bob", "Mary", "James"],name = 'person')
cols = ['age','city']
data = [[18,'Beijing'],
[30,'ShangHai'],
[25,'GuangZhou'],
[40,'ShenZhen']]
df =pd.DataFrame(index = index,data =data,columns = cols)
df
複製代碼
age | city | |
---|---|---|
person | ||
Tom | 18 | Beijing |
Bob | 30 | ShangHai |
Mary | 25 | GuangZhou |
James | 40 | ShenZhen |
這裏的主要區別在於咱們主動規定了‘name’列爲索引。這種把一列默認爲索引的方式在excel和sql裏都有,殊途同歸
從其餘數據源讀取(網站,excel,mysql等)
我會在第三部分介紹最經常使用的從excel,csv等讀取數據
整體來講,有關建立Dataframe的部分咱們不用瞭解太多,由於實際的場景基本不須要,都是直接從csv,tsv,sql,json等數據源直接獲取。
這裏咱們主要看一下基於索引,行,列,行和列的基礎操做,最後會爲你們總結一下,如今拿剛剛咱們建立過的dataframe爲例:
age | city | name | |
---|---|---|---|
0 | 18 | Beijing | Tom |
1 | 30 | ShangHai | Bob |
2 | 25 | GuangZhou | Mary |
3 | 40 | ShenZhen | James |
添加新列
添加一列很是簡單:
df['country'] = 'USA'
df
複製代碼
age | city | name | country | |
---|---|---|---|---|
0 | 18 | Beijing | Tom | USA |
1 | 30 | ShangHai | Bob | USA |
2 | 25 | GuangZhou | Mary | USA |
3 | 40 | ShenZhen | James | USA |
df['adress'] = df['country']
df
複製代碼
age | city | name | country | adress | |
---|---|---|---|---|---|
0 | 18 | Beijing | Tom | USA | USA |
1 | 30 | ShangHai | Bob | USA | USA |
2 | 25 | GuangZhou | Mary | USA | USA |
3 | 40 | ShenZhen | James | USA | USA |
修改列中的值
修改一個列的值也是很容易的,咱們能夠這樣作:
df['country'] = 'China'
df
複製代碼
age | city | name | country | adress | |
---|---|---|---|---|---|
0 | 18 | Beijing | Tom | China | USA |
1 | 30 | ShangHai | Bob | China | USA |
2 | 25 | GuangZhou | Mary | China | USA |
3 | 40 | ShenZhen | James | China | USA |
或者稍微多想一步:
df['adress'] = df['city']+','+ df['country']
df
複製代碼
age | city | name | country | adress | |
---|---|---|---|---|---|
0 | 18 | Beijing | Tom | China | Beijing,China |
1 | 30 | ShangHai | Bob | China | ShangHai,China |
2 | 25 | GuangZhou | Mary | China | GuangZhou,China |
3 | 40 | ShenZhen | James | China | ShenZhen,China |
刪除列
咱們能夠應用del或者drop函數,若是是drop,要注意傳參時要加上axis = 1.這裏簡單和你們說明一下axis,這個東西其實就是指軸向,默認的axis=0,是縱向,axis=1是橫向
df.drop('country',axis=1)
df
複製代碼
age | city | name | adress | |
---|---|---|---|---|
0 | 18 | Beijing | Tom | Beijing,China |
1 | 30 | ShangHai | Bob | ShangHai,China |
2 | 25 | GuangZhou | Mary | GuangZhou,China |
3 | 40 | ShenZhen | James | ShenZhen,China |
del df['city']
df
複製代碼
age | name | adress | |
---|---|---|---|
0 | 18 | Tom | Beijing,China |
1 | 30 | Bob | ShangHai,China |
2 | 25 | Mary | GuangZhou,China |
3 | 40 | James | ShenZhen,China |
這裏有一點你們須要注意:
所以若是咱們想要連續刪除country和city這兩列,改進後的代碼以下:
df.drop('country',axis=1, inplace=True)
del df['city']
df
複製代碼
age | name | adress | |
---|---|---|---|
0 | 18 | Tom | Beijing,China |
1 | 30 | Bob | ShangHai,China |
2 | 25 | Mary | GuangZhou,China |
3 | 40 | James | ShenZhen,China |
選取列
這個很是簡單,實現代碼以下:
df['age'] # 選取age這一列
0 18
1 30
2 25
3 40
Name: age, dtype: int64
複製代碼
或者這樣:
df.name
複製代碼
0 Tom
1 Bob
2 Mary
3 James
Name: name, dtype: object
複製代碼
若是想要選取多個列也很容易,傳遞一個list就行啦:
df[['age','name']]
複製代碼
age | name | |
---|---|---|
0 | 18 | Tom |
1 | 30 | Bob |
2 | 25 | Mary |
3 | 40 | James |
這裏注意,和選取單獨一列不一樣,這裏咱們返回的類型是dataframe,以前的類型是series,咱們能夠這麼理解,一列其實仍是一維數組,可是兩列及以上是二維的了,固然類型也變了
若是咱們想要查看當前的全部列:
df.columns
Out:Index([u'age', u'name', u'adress'], dtype='object')
複製代碼
若是咱們想要從新對列進行命名,基本有三種方法,你們挑一種本身喜歡的就行
用list:
df.columns = ['Age','Name','Adress']
df
複製代碼
用dict:
df.rename(index = str, columns = {'age':'Age','name':'Name','adress':'Adress'}) #這裏index=str 有沒有都行,我這麼作是爲了規範
df
複製代碼
用axis:
df.rename(str.capitalize, axis='columns',inplace =True)
df
複製代碼
最後獲得的效果是同樣的:
Age | Name | Adress | |
---|---|---|---|
0 | 18 | Tom | Beijing,China |
1 | 30 | Bob | ShangHai,China |
2 | 25 | Mary | GuangZhou,China |
3 | 40 | James | ShenZhen,China |
根據條件給列賦值
咱們如今想要根據人的年齡新增一列 Group,假設要求以下:
咱們有不少方法能夠實現,先看一種,你們能夠先忽視loc方法,這裏傳達的就是基礎思路:
df['Group'] = 'elderly'
df.loc[df['Age']<=18, 'Group'] = 'young'
df.loc[(df['Age'] >18) & (df['Age'] <= 30), 'Group'] = 'middle_aged'
df
複製代碼
Age | Name | Adress | Group | |
---|---|---|---|---|
0 | 18 | Tom | Beijing,China | young |
1 | 30 | Bob | ShangHai,China | middle_aged |
2 | 25 | Mary | GuangZhou,China | middle_aged |
3 | 40 | James | ShenZhen,China | elderly |
loc函數 df.loc[row,column]
首先,大多數對於行的操做均可以經過loc函數實現,好比咱們想要選取所有的行,除了直接打出df外,可使用df.loc[:]
df.loc[:]
複製代碼
Age | Name | Adress | Group | |
---|---|---|---|---|
0 | 18 | Tom | Beijing,China | young |
1 | 30 | Bob | ShangHai,China | middle_aged |
2 | 25 | Mary | GuangZhou,China | middle_aged |
3 | 40 | James | ShenZhen,China | elderly |
loc函數條件查詢
df.loc[df['Age']>20]
複製代碼
Name | Age | Adress | Group | |
---|---|---|---|---|
1 | Bob | 30 | ShangHai,China | middle_aged |
2 | Mary | 25 | GuangZhou,China | middle_aged |
3 | James | 40 | ShenZhen,China | elderly |
loc函數條件行列查詢
df.loc[df['Group']=='middle_aged','Name']
1 Bob
2 Mary
Name: Name, dtype: object
複製代碼
Where 查詢
filter_adult = df['Age']>25
result = df.where(filter_adult)
result
複製代碼
Name | Age | Adress | Group | |
---|---|---|---|---|
0 | NaN | NaN | NaN | NaN |
1 | Bob | 30.0 | ShangHai,China | middle_aged |
2 | NaN | NaN | NaN | NaN |
3 | James | 40.0 | ShenZhen,China | elderly |
Query 篩選
# df.query('Age==30')
df.query('Group=="middle_aged"'and 'Age>30' )
複製代碼
Name | Age | Adress | Group | |
---|---|---|---|---|
3 | James | 40 | ShenZhen,China | elderly |
這裏有不少有用的方法,能夠幫助到你們大體瞭解數據的狀況:
df.shape # 瞭解行列狀況
Out:(4, 4)
複製代碼
df.describe() # 獲取可計算列基礎統計
複製代碼
Age | |
---|---|
count | 4.000000 |
mean | 28.250000 |
std | 9.251126 |
min | 18.000000 |
25% | 23.250000 |
50% | 27.500000 |
75% | 32.500000 |
max | 40.000000 |
# df.head(3) #查看前三行數據,默認爲5
df.tail(3) #得到最後三行數據
複製代碼
Name | Age | Adress | Group | |
---|---|---|---|---|
1 | Bob | 30 | ShangHai,China | middle_aged |
2 | Mary | 25 | GuangZhou,China | middle_aged |
3 | James | 40 | ShenZhen,China | elderly |
Pandas 支持大部分常見數據文件讀取與存儲。通常清楚下,讀取文件的方法以 pd.read_ 開頭,而寫入文件的方法以 pd.to_ 開頭。這裏咱們開始熟悉一下最實用的對於csv文件的讀取寫入
寫入CSV
df.to_csv('person.csv',index=None,sep=',')
複製代碼
import os
os.getcwd()
Out: 'C:\\Users\\E560'
複製代碼
這樣你們就能夠在'C:\Users\E560'的路徑下找到咱們剛剛生成的csv文件了,這裏我把index=None,捨棄了索引值
讀取CSV
首先咱們確認和python文件同一目錄下存在咱們剛剛導出的person.csv文件,以後能夠很容易的讀取了:
person = pd.read_csv('person.csv')
person
複製代碼
Name | Age | Adress | Group | |
---|---|---|---|---|
0 | Tom | 18 | Beijing,China | young |
1 | Bob | 30 | ShangHai,China | middle_aged |
2 | Mary | 25 | GuangZhou,China | middle_aged |
3 | James | 40 | ShenZhen,China | elderly |
這時咱們發現,即便咱們讀取的csv文件沒有索引,可是pandas已經默認幫咱們加上了
好了,如今你們對pandas的使用已經有了基礎的印象,我給你們簡單總結一下經常使用的方法:
使用標籤選取數據
df.loc[行標籤,列標籤]
df.loc['Tom':'Mary'] #選取 Tom至Mary的全部行的數據,Tom和Mary是index
df.loc[:,'city'] #選取 city 列的數據
複製代碼
df.loc 的第一個參數是行標籤,第二個參數爲列標籤(可選參數,默認爲全部列標籤),兩個參數既能夠是列表也能夠是單個字符,若是兩個參數都爲列表則返回的是 DataFrame,不然,則爲 Series。
PS:loc爲location的縮寫。
使用位置(index)選取數據
df.iloc[行位置,列位置]
df.iloc[1,1] #選取第二行,第二列的值,返回的爲單個值
df.iloc[[0,2],:] #選取第一行及第三行的數據
df.iloc[0:2,:] #選取第一行到第三行(不包含)的數據
df.iloc[:,1] #選取全部記錄的第二列的值,返回的爲一個Series
df.iloc[1,:] #選取第一行數據,返回的爲一個Series
複製代碼
PS:iloc 則爲 integer & location 的縮寫
經過邏輯指針進行數據切片
df[邏輯條件]
df[df.age >= 18] #單個邏輯條件
df[(df.age >=18 ) & (df.country=='China') ] #多個邏輯條件組合
複製代碼
瞭解並掌握數據大體狀況
方法 | 解釋 |
---|---|
count | 非na值的數量 |
describe | 針對Series或個DataFrame列計算彙總統計 |
min、max | 計算最小值和最大值 |
argmin、argmax | 計算可以獲取到最大值和最小值得索引位置(整數) |
idxmin、idxmax | 計算可以獲取到最大值和最小值得索引值 |
quantile | 計算樣本的分位數(0到1) |
sum | 值的總和 |
mean | 值得平均數 |
median | 值得算術中位數(50%分位數) |
mad | 根據平均值計算平均絕對離差 |
var | 樣本值的方差 |
std | 樣本值的標準差 |
skew | 樣本值得偏度(三階矩) |
kurt | 樣本值得峯度(四階矩) |
cumsum | 樣本值得累計和 |
cummin,cummax | 樣本值得累計最大值和累計最小值 |
cumprod | 樣本值得累計積 |
diff | 計算一階差分(對時間序列頗有用) |
pct_change | 計算百分數變化 |
常見讀取寫入數據
數據類型 | 讀取 | 寫入 |
---|---|---|
CSV | read_csv | to_csv |
JSON | read_json | to_json |
HTML | read_html | to_html |
EXCEL | read_excel | to_excel |
SQL | read_sql | to_sql |
好了,其實這些就是想要告訴你們如何學習pandas,沒有必要了解每個方法,可是如今想必你知道pandas能實現的功能不少,這樣你有具體需求時只要詳細查詢一下文檔便可,接下來幾期咱們會重點來看pandas裏面對於df的各類操做,從簡單的數據清理到相似於excel裏面的vba,包括cancat,merge,join等等
下載
我把這一期的ipynb文件和py文件放到了GIthub上,你們若是想要下載能夠點擊下面的連接: