Pandas從入門到精通(1)- 基礎(chǔ)

我們都知道Python之所有能在數(shù)據(jù)科學(xué)領(lǐng)域占有一席之地险毁,主要是數(shù)據(jù)分析三劍客:numpy霍衫、pandas候引、matplotlib這三個(gè)庫的功勞。而在這三個(gè)庫中敦跌,我覺得最核心澄干,用的最多的還是pandas。不管是在平時(shí)處理數(shù)據(jù)還是打比賽中柠傍,都要求能夠?qū)andas進(jìn)行熟練的應(yīng)用麸俘。基于此惧笛,筆者參加了Datawhale開源社區(qū)組織的Pandas學(xué)習(xí)从媚,目標(biāo)就是爆肝一個(gè)月,精通Pandas!

從本期開始患整,我們就開始來系統(tǒng)學(xué)習(xí)并梳理一下Pandas的知識拜效。我們將按照下面的大綱分10期進(jìn)行。我相信通過通過10期豐富的案例學(xué)習(xí)并级,掌握并熟練運(yùn)用Pandas拂檩,水到渠成。

  • Pandas基礎(chǔ)
  • 索引
  • 分組
  • 變形
  • 連接
  • 缺失數(shù)據(jù)
  • 文本數(shù)據(jù)
  • 分類數(shù)據(jù)
  • 時(shí)序數(shù)據(jù)
  • 綜合練習(xí)

本期作為第一期嘲碧,主要是熟悉一些基礎(chǔ)知識稻励,為后期的學(xué)習(xí)做準(zhǔn)備。主要包括Python中的一些常用函數(shù)和numpy庫的一些操作愈涩。

1.1 列表推導(dǎo)式

列表推導(dǎo)式是Python語言的一大特色望抽,可以快速簡潔的創(chuàng)建列表。

1.1.1 基本格式:

[* for i in k]: * 可以是一個(gè)函數(shù)履婉,變量為i(也可以與i無關(guān))煤篙,k為一個(gè)可迭代對象,如列表毁腿。
應(yīng)用: 1. 一句代碼輸出一個(gè)1到5的立方

  1. 一句代碼創(chuàng)建一個(gè)列表辑奈,包含10個(gè)60-100的隨機(jī)整數(shù)
# 一句代碼輸出一個(gè)1到5的立方
[i**3 for i in range(1,6)]
>>>[1, 8, 27, 64, 125]
# 一句代碼創(chuàng)建一個(gè)列表,包含10個(gè)60-100的隨機(jī)整數(shù)(模擬學(xué)生成績)
import random
[random.randint(60,100) for _ in range(10)]
>>> [76, 89, 62, 83, 61, 80, 89, 99, 76, 78]

1.1.2 for循環(huán)嵌套

列表推導(dǎo)式中的for循環(huán)支持嵌套功能已烤。
舉例: 現(xiàn)有3個(gè)列表分別保存了顧客的姓名鸠窗,衣服的顏色,尺碼胯究,用一句代碼輸出所有顧客和衣服顏色尺碼的組合

names = ['zhangsan', 'lisi', 'wangba']
color = ['red', 'yellow']
size = ['S', 'M', 'L']
[name + '-' + c + '-' + s for name in names for c in color for s in size]
>>>
['zhangsan-red-S',
 'zhangsan-red-M',
 'zhangsan-red-L',
 'zhangsan-yellow-S',
 'zhangsan-yellow-M',
 'zhangsan-yellow-L',
 'lisi-red-S',
 'lisi-red-M',
 'lisi-red-L',
 'lisi-yellow-S',
 'lisi-yellow-M',
 'lisi-yellow-L',
 'wangba-red-S',
 'wangba-red-M',
 'wangba-red-L',
 'wangba-yellow-S',
 'wangba-yellow-M',
 'wangba-yellow-L']

上面的代碼等價(jià)于:

for name in names:
    for c in color:
        for s in size:
            print(name + '-' + c + '-' + 's')
>>>
zhangsan-red-s
zhangsan-red-s
zhangsan-red-s
zhangsan-yellow-s
zhangsan-yellow-s
zhangsan-yellow-s
lisi-red-s
lisi-red-s
lisi-red-s
lisi-yellow-s
lisi-yellow-s
lisi-yellow-s
wangba-red-s
wangba-red-s
wangba-red-s
wangba-yellow-s
wangba-yellow-s
wangba-yellow-s

1.1.3 篩選功能

列表推導(dǎo)式中for循環(huán)后還可以加入if (或者if...else...)進(jìn)行篩選 稍计。
舉例: 一句代碼輸出0-100內(nèi)可以被7整除的整數(shù)

# 輸出1-100內(nèi)可以被7整除的數(shù):
[i for i in range(1,101) if i%7 == 0]
>>>
[7, 14, 21, 28, 35, 42, 49, 56, 63, 70, 77, 84, 91, 98]

綜合上面的案例,我們可以清晰的看到列表推導(dǎo)式的簡潔與優(yōu)雅裕循!同時(shí)也體現(xiàn)Python的強(qiáng)大之處臣嚣。

1.2 lambda匿名函數(shù)

我們都知道函數(shù)在python世界中屬于一等公民净刮,具有很高的權(quán)限。對于經(jīng)常需要重復(fù)使用的代碼塊硅则,一般都要優(yōu)先考慮通過函數(shù)來實(shí)現(xiàn)淹父。但是當(dāng)我們想要使用一個(gè)簡單定義的,或者只需要調(diào)用一兩次的函數(shù)時(shí)怎虫,取名并編寫一個(gè)完整的函數(shù)塊就顯得多余弹灭。這時(shí)候lambda匿名函數(shù)就有了用武之地。
格式: lambda [arg1 [,arg2, ... argN]] : expression
這里的lamdbda是系統(tǒng)保留的關(guān)鍵字揪垄, [arg1 [,arg2, ... argN]]是參數(shù)列表,它的結(jié)構(gòu)與Python中函數(shù)(function)的參數(shù)列表是一樣的逻翁。expression是一個(gè)關(guān)于參數(shù)的表達(dá)式饥努。表達(dá)式中出現(xiàn)的參數(shù)需要在argument_list中有定義,并且表達(dá)式只能是單行的八回。
舉例:例如我們定義一個(gè)函數(shù)酷愧,將字符串中的所有字母大寫輸出

def str_capital(s):
    return str.upper(s)

str_capital('datawhale')
>>>
'DATAWHALE'

如果改用匿名函數(shù)的寫法:

upper = lambda x: str.upper(x)
upper('datawhale')
>>>
'DATAWHALE'

對比一下可以看到匿名函數(shù)有如下優(yōu)點(diǎn):

  • 可以直接在使用的地方定義,如果需要修改缠诅,直接找到修改即可溶浴,方便以后代碼的維護(hù)工作
  • 語法結(jié)構(gòu)簡單,不用使用def 函數(shù)名(參數(shù)名):這種方式定義管引,直接使用lambda 參數(shù):返回值 定義即可
    但是需要注意的是lambda匿名函數(shù)讓程序簡潔士败,但是并不能讓程序高效,這個(gè)也是很多程序員反對使用lambda的原因褥伴。

1.3 map()方法

在Python中谅将,匿名函數(shù)lambda經(jīng)常和map()、reduce()和filter()三個(gè)應(yīng)用于序列的內(nèi)置函數(shù)聯(lián)合使用重慢,用于對序列進(jìn)行遍歷饥臂、遞歸計(jì)算以及篩選。這其中似踱,最常用的就是map方法隅熙。在Python中,map()函數(shù)的本質(zhì)是一種映射,即對輸入其中的可迭代對象(列表)中每個(gè)元素執(zhí)行定義的映射核芽。例如我們編寫了一個(gè)將給定的字符串大寫輸出的函數(shù)囚戚,在使用該函數(shù)將若干字符串大寫輸出

def str_capital(s):
    return str.upper(s)
L1 = ['I', 'like', 'Datawhale']
L2 = []
for s in L1:
    L2.append(str_capital(s))
L2
>>> 
['I', 'LIKE', 'DATAWHALE']

如果我們用map()替代for循環(huán):

L3 = map(str_capital, L1)
list(L3)
>>>
['I', 'LIKE', 'DATAWHALE']

可以看到更加簡潔!需要注意的是map()方法返回的是一個(gè)map()對象狞洋,需要用list()方法輸出其中的元素弯淘。上面我們說了map經(jīng)常和lambda匿名函數(shù)結(jié)合使用,如下:

L4 = map(lambda x: str.upper(x), L1)
list(L4)
>>>
['I', 'LIKE', 'DATAWHALE']

優(yōu)雅吉懊!

1.4 zip方法

我們都知道zip是一個(gè)文件解壓程序庐橙,同樣的假勿,在python中zip()函數(shù)就有點(diǎn)類似于解壓縮包的感覺:傳入一個(gè)列表或者其他可迭代對象,依次從中選取一個(gè)組成新的元組輸出态鳖。下面舉例:

a = [3,4,5,6]
b = ['a', 'b', 'c']
s1 = {'zhangsan': 20, 'lisi': 25}
print(zip(a))
print('*' * 10)
print(list(zip(a)))
print(list(zip(b)))
print(list(zip(s1)))
>>>
<zip object at 0x000001A7D4FF7940>
**********
[(3,), (4,), (5,), (6,)]
[('a',), ('b',), ('c',)]
[('zhangsan',), ('lisi',)]

可以看到zip的輸出也是一個(gè)zip對象转培,需要用list查看其中的元素。
當(dāng)zip()函數(shù)有兩個(gè)參數(shù)時(shí) 浆竭,如zip(a,b),則分別從a和b依次各取出一個(gè)元素組成元組邦泄,再將依次組成的元組組合成一個(gè)新的迭代器。如:

print(list(zip(a,b)))
>>>
[(3, 'a'), (4, 'b'), (5, 'c')]

這樣設(shè)計(jì)有個(gè)特殊的用途顺囊,用于矩陣(二維數(shù)組)的加減和點(diǎn)乘,舉例如下:

import numpy as np
m = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
n = [[2, 2, 2], [3, 3, 3], [4, 4, 4]]
# 矩陣點(diǎn)乘
print('=*'*10 + "矩陣點(diǎn)乘" + '=*'*10)
print(np.array([x*y for a, b in zip(m, n) for x, y in zip(a, b)]).reshape(3,3))
# 矩陣相加,相減雷同
print('=*'*10 + "矩陣相加,相減" + '=*'*10)
print(np.array([x+y for a, b in zip(m, n) for x, y in zip(a, b)]).reshape(3,3))
>>>
=*=*=*=*=*=*=*=*=*=*矩陣點(diǎn)乘=*=*=*=*=*=*=*=*=*=*
[[ 2  4  6]
 [12 15 18]
 [28 32 36]]
=*=*=*=*=*=*=*=*=*=*矩陣相加,相減=*=*=*=*=*=*=*=*=*=*
[[ 3  4  5]
 [ 7  8  9]
 [11 12 13]]

知識鏈接:矩陣點(diǎn)乘
矩陣點(diǎn)乘: 對應(yīng)元素相乘,要求兩個(gè)矩陣的形狀必須相同特碳。這個(gè)要和矩陣叉乘區(qū)分開來诚亚。

2. Numpy復(fù)習(xí)回顧

pandas是基于numpy來實(shí)現(xiàn)高效計(jì)算的午乓,因而在學(xué)習(xí)pandas之前有必要先把之前學(xué)習(xí)的numpy的知識溫習(xí)一下站宗,這里總結(jié)了一些numpy一些常用的知識點(diǎn)

2.1 np.array

np里面最基本的數(shù)據(jù)結(jié)構(gòu)是array(數(shù)組)益愈,構(gòu)造也非常簡單梢灭,np.array即可。下面總結(jié)幾種特殊的array

  1. 等差序列
  • np.linspace(起始蒸其,終止(包含)或辖,樣本個(gè)數(shù)): 適用于提前知道需要?jiǎng)?chuàng)建多少個(gè)樣本的情況
  • np.arange(起始枣接,終止(不包含),步長): 適用于提前知道相鄰間隔的情況
    注意 np.arange和python數(shù)組中的range不要混淆了但惶。range只能生成整數(shù)數(shù)列,而np.arange可以生成小數(shù)數(shù)列
import numpy as np
a = np.linspace(1,100,10)
b = np.arange(1,10,1.5)
print(a)
print(b)
>>>
[  1.  12.  23.  34.  45.  56.  67.  78.  89. 100.]
[1.  2.5 4.  5.5 7.  8.5]
    1. 特殊矩陣县爬,包括zeros/ones/eye/full等
      直接上代碼參考:
print('3行4列全0矩陣')
print(np.zeros((3,4)))
print('*' * 10)
print('3行3列全1矩陣')
print(np.ones((3, 3)))
print('*' * 10)
print('3行3列的單位矩陣')
print(np.eye(3))
print('*' * 10)
print('指定維度的/數(shù)值填充矩陣')
print(np.full((2,3), 6))
>>>
3行4列全0矩陣
[[0. 0. 0. 0.]
 [0. 0. 0. 0.]
 [0. 0. 0. 0.]]
**********
3行3列全1矩陣
[[1. 1. 1.]
 [1. 1. 1.]
 [1. 1. 1.]]
**********
3行3列的單位矩陣
[[1. 0. 0.]
 [0. 1. 0.]
 [0. 0. 1.]]
**********
指定維度的/數(shù)值填充矩陣
[[6 6 6]
 [6 6 6]]
    1. 隨機(jī)矩陣
  • np.random.rand() : 取值0-1之間的隨機(jī)分布添谊,這里不要傳元組财喳,直接指定不同維度的個(gè)數(shù)即可
  • np.random.randn(): 0~1標(biāo)準(zhǔn)正態(tài)分布
  • np.random.randint(low,high,size) :指定生成隨機(jī)整數(shù)的最小值最大值和維度大小
  • np.random.choice(): 可以從給定的列表中,以一定概率和方式抽取結(jié)果扎瓶,當(dāng)不指定概率時(shí)為均勻采樣泌枪,默認(rèn)抽取方式為有放回抽樣
  • np.random.seed(0) : 設(shè)置種子,就相當(dāng)是設(shè)定了隨機(jī)值碌燕,之后每次隨機(jī)都一樣

2. 練習(xí)題:

  1. 使用列表推導(dǎo)式完成矩陣乘法:
    矩陣乘法定義:


    image.png

    一般的矩陣乘法根據(jù)公式,可以由三重循環(huán)寫出:


    image.png

使用列表推導(dǎo)式來替代for循環(huán)完成

# 先定義零個(gè)矩陣
M1 = np.random.randint(1,10,10).reshape(2,5)
M2 = np.random.randint(1,10,10).reshape(5,2)
print(M1)
print('-' * 5)
print(M2)
M1@M2 # 矩陣乘法
>>>
[[6 1 2 8 5]
 [6 1 7 9 4]]
-----
[[6 2]
 [7 7]
 [1 4]
 [7 1]
 [8 3]]
array([[141,  50],
       [145,  68]])
# 使用列表推導(dǎo)式來完成
[[sum([M1[i][k] * M2[k][j] for k in range(M1.shape[1])]) for j in range(M2.shape[1])] for i in range(M1.shape[0])]
>>>
[[141, 50], [145, 68]]
  1. 更新矩陣
    設(shè)矩陣 Am×n 愈捅,現(xiàn)在對 A 中的每一個(gè)元素進(jìn)行更新生成矩陣 B 慈鸠,更新方法是


    image.png

例如下面的矩陣為 A ,則 B_{2,2}=5×(1/4+1/5+1/6)=37/12 林束,請利用 Numpy 高效實(shí)現(xiàn)稽亏。

image.png

解答:

A = np.arange(1,10).reshape(3,3)
B = A*(1/A).sum(1).reshape(-1,1)
image.png

使用內(nèi)置的函數(shù)

B = A.sum(0) * A.sum(1).reshape(-1,1) / A.sum()
print(B)
res = ((A-B) ** 2 / B).sum()
print(res)

參考:開源內(nèi)容Joyful Pandas, 作者 DataWhale耿遠(yuǎn)昊
另外,更多精彩內(nèi)容也可以微信搜索胖腾,并關(guān)注公眾號:‘Python數(shù)據(jù)科學(xué)家之路“ ,期待您的到來和我交流

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末咸作,一起剝皮案震驚了整個(gè)濱河市记罚,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌桐智,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件说庭,死亡現(xiàn)場離奇詭異郑趁,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進(jìn)店門舅柜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來攻礼,“玉大人业踢,你說我怎么就攤上這事礁扮。” “怎么了太伊?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長锰提。 經(jīng)常有香客問我芳悲,道長立肘,這世上最難降的妖魔是什么名扛? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮融蹂,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘超燃。我一直安慰自己拘领,他們只是感情好意乓,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布约素。 她就那樣靜靜地躺著,像睡著了一般业汰。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上样漆,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天,我揣著相機(jī)與錄音鳍怨,去河邊找鬼呻右。 笑死,一個(gè)胖子當(dāng)著我的面吹牛声滥,可吹牛的內(nèi)容都是我干的侦香。 我是一名探鬼主播落塑,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼憾赁,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了龙考?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤晦款,失蹤者是張志新(化名)和其女友劉穎枚冗,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體官紫,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡州藕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了毁涉。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片锈死。...
    茶點(diǎn)故事閱讀 38,137評論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖待牵,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情缨该,我是刑警寧澤,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站蛤袒,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏缴允。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一练般、第九天 我趴在偏房一處隱蔽的房頂上張望菱阵。 院中可真熱鬧,春花似錦晴及、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽歌懒。三九已至溯壶,卻和暖如春及皂,著一層夾襖步出監(jiān)牢的瞬間且改,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工碍拆, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留慨蓝,地道東北人感混。 一個(gè)月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓礼烈,卻偏偏與公主長得像,于是被迫代替她去往敵國和親谱秽。 傳聞我的和親對象是個(gè)殘疾皇子洽蛀,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內(nèi)容