為什么你需要pandas
大家好,今天想和大家分享一下有關pandas的學習新的,我因工作需要,從去年12月開始接觸這個非常好用的包,到現在為止也是算是熟悉了一些,因此發現了它的強大之處,特意想要和朋友們分享,特別是如果你每天和excel打交道,總是需要編寫一些vba函數或者對行列進行groupby啊,merge,join啊之類的,相信我,pandas會讓你解脫的。
好啦,閑話少說,這篇文章的基礎是假設你已經大概聽說過了pandas的一些概念和用途,如果還大體上不太清楚的朋友們,可以去百度一下相關基礎介紹,本分主要分成四個部分:
從Dataframe說起 : 簡單了解Df這種數據結構,了解如何創建一個Df
Dataframe基礎操作 :基于行,列,index選取數據,新增數據,刪除數據
Pandas 讀取 / 導出數據: 了解如何對excel,csv,tsv等常見文件進行讀取并導出
總結: 精華部分,為大家總結一些非常實用的一些方法,并附帶源碼 ipynb以及py文件提供下載
1. 從Dataframe說起首先,讓我們明確一點,pandas這個包是在numpy的基礎上得到的,因此可能有的朋友會有疑問,要不要先學學numpy,我的個人建議是真的不太需要,因為大多數的情況下基本用不到,當然,如果你處理的是科學實驗類型的數據的話,當我沒說,我這里的應用場景主要是一般類型的常見數據,比如:
你是銷售經理,經常需要匯總各地區的銷售情況
你在銀行工作,不可避免的需要和數字,excel打交道
你每天有很多重復的工作,比如備份,計算兩表合并,分組,聚類等等。。。。。。
這種情況下,學習pandas會非常有用,這里我們說的數據都是二維的table,在pandas中也稱作dataframe。
pandas中其實一共有三種類型的常見數據:
數據結構 | 維度 | 說明 |
---|---|---|
Series | 1 | 類似list,一維數組 |
Data Frames | 2 | 最常見的二維數據結構,excel,sql的表就是這個 |
Panel | 3 | 用的很少,三維結構 |
pandas主要包括三類數據結構,分別是:
Series:一維數組,與Numpy中的一維array類似。二者與Python基本的數據結構List也很相近,其區別是:List中的元素可以是不同的數據類型,而Array和Series中則只允許存儲相同的數據類型,這樣可以更有效的使用內存,提高運算效率。
DataFrame:二維的表格型數據結構。很多功能與R中的data.frame類似。可以將DataFrame理解為Series的容器。以下的內容主要以DataFrame為主。
Panel :三維的數組,可以理解為DataFrame的容器。
Pandas官網,更多功能請參考 http://pandas-docs.github.io/...
這里我們主要聚焦在Dataframe上,一個dataframe長的基本上如下這番模樣:
Name | Age | Mark |
---|---|---|
John | 15 | 78 |
Mike | 23 | 86 |
Mary | 36 | 95 |
我們把這個簡單的dataframe起個名字叫df,那么它包括的最基礎的元素有:
index:每行的索引,默認是從0開始,比如上面的df[0] 就是指 John 15 78這一行,依次類推,當然我們可以自己規定index,我以后會說
columns:列。這里就是指的是Name Age Mark 了
rows:行,df一共有3行
現在讓我們看一個完整的圖示:
Dataframe 是應用最多也是最廣泛的數據結構,現在就讓我們開始學習創建一個dataframe吧~
1.1 創建Dataframe創建一個Dataframe的方法有很多,總體上來說最常見的有及種:
創建空dataframe
利用dict創建
從其他數據源讀取(網站,excel,mysql等)
真實場景中大多數都是從其他數據源讀取,我們會在第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等數據源直接獲取。
2. Dataframe 基礎操作這里我們主要看一下基于索引,行,列,行和列的基礎操作,最后會為大家總結一下,現在拿剛剛我們創建過的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 |
這里有一點大家需要注意:
drop和del的結果是基于df的兩次多帶帶操作,并不是連續的
如果我們執行完drop后,重新查看df,這時你會發現df沒有變化,因為沒有真正的刪除
要想真正刪除,需要加上關鍵字 inplace = True
因此如果我們想要連續刪除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
傳遞dict
傳遞 axis
用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,假設要求如下:
18歲以下的是年輕人
18-30的是中年人
30以上的是老年人
我們有很多方法可以實現,先看一種,大家可以先忽視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:UsersE560"
這樣大家就可以在"C:UsersE560"的路徑下找到我們剛剛生成的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已經默認幫我們加上了
4. 總結,資料下載好了,現在大家對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上,大家如果想要下載可以點擊下面的鏈接:
Github倉庫地址: 點我下載
好啦,這一期就講這么多,希望大家能夠繼續支持我,完結,撒花
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/43298.html
摘要:數據清洗大家好,這一期我將為大家帶來我的學習心得第二期數據清理。這一期我會和大家分享一些比較好用常見的清洗方法。首先還是讓我們來簡單看一下本文將會用到的數據源這是一個超小型的房地產行業的數據集,大家會在文章最后找到下載地址。 數據清洗 大家好,這一期我將為大家帶來我的pandas學習心得第二期:數據清理。這一步非常重要,一般在獲取數據源之后,我們緊接著就要開始這一步,以便為了之后的各種...
摘要:,同為小白的朋友們大家好,這期主要為大家帶來有關字典的一些實用技巧。上篇筆記通過感人肺腑的老白讓大家認識到了字典這么有用的數據類型,這一期讓我們看看如何能更好的操作字典。 Hello ,同為小白的朋友們大家好,這期主要為大家帶來有關字典的一些實用技巧。上篇筆記通過感人肺腑的老白讓大家認識到了字典這么有用的數據類型,這一期讓我們看看如何能更好的操作字典。 基礎篇 下面我給大家來一個簡單的...
摘要:如何根據需要創建簡單模型大家好,今天這一期我想和大家分享有關于創建模型的部分,首先讓我們來看一個比較常見的場景你每天需要打開個進行相同的操作,各種眼花繚亂的函數后老眼昏花。。。。 Pandas 如何根據需要創建簡單模型 大家好,今天這一期我想和大家分享有關于pandas創建模型的部分,首先讓我們來看一個比較常見的場景: 你每天需要打開N個excel進行相同的操作,各種眼花繚亂的VBA函...
摘要:下面讓我們開始提速假設我們現在的電價是定值,不根據用電時間段來改變,那么中最快的方法那就是采用,這就是一個簡單的矢量化操作示范。它基本是在中運行最快的方式。 Pandas 加速 大家好,今天我們來看有關pandas加速的小技巧,不知道大家在剛剛接觸pandas的時候有沒有聽過如下的說法 pandas太慢了,運行要等半天 其實我想說的是,慢不是pandas的錯,大家要知道pandas本身...
摘要:基于上的我們還可以實現幾個基于的,還是老樣子,先讓我們創建兩個好了,現在我們想要實現兩個的,但是條件是通過的和的這樣我們也可以得到結果。 Merge, Join, Concat 大家好,我有回來啦,這周更新的有點慢,主要是因為我更新了個人簡歷哈哈,如果感興趣的朋友可以去看看哈: 我的主頁 個人認為還是很漂亮的~,不得不說,很多時候老外的設計能力還是很強。 好了,有點扯遠了,這一期我想和...
閱讀 1506·2021-11-25 09:43
閱讀 4057·2021-11-15 11:37
閱讀 3191·2021-08-17 10:13
閱讀 3503·2019-08-30 14:16
閱讀 3533·2019-08-26 18:37
閱讀 2487·2019-08-26 11:56
閱讀 1128·2019-08-26 10:42
閱讀 608·2019-08-26 10:39