第1章 入門(mén)知識(shí)
- 簡(jiǎn)述:用于操作行列數(shù)據(jù),方便地實(shí)現(xiàn)各種形式的數(shù)據(jù)分析;
- Pandas最初主要應(yīng)用于金融數(shù)據(jù)分析工作,其為時(shí)間序列分析提供了很好的支持;
- Pandas的名稱(chēng)來(lái)自于面板數(shù)據(jù)
(panel data)
和Python數(shù)據(jù)分析(data analysis)
; -
panel data
是經(jīng)濟(jì)學(xué)中關(guān)于多維數(shù)據(jù)集的一個(gè)術(shù)語(yǔ),在Pandas中也提供了panel的數(shù)據(jù)類(lèi)型(新版本已停用); - 適用的數(shù)據(jù)類(lèi)型
- 具有異構(gòu)類(lèi)型列的表格數(shù)據(jù),如SQL表格或Excel數(shù)據(jù);
- 有序和無(wú)序(不一定是固定頻率)時(shí)間序列數(shù)據(jù);
- 具有行列標(biāo)簽的任意矩陣數(shù)據(jù)(均勻類(lèi)型或不同類(lèi)型);
- 任何其他形式的觀(guān)測(cè)/統(tǒng)計(jì)數(shù)據(jù)集。
第2章 數(shù)據(jù)結(jié)構(gòu)
- 作為一個(gè)python庫(kù),python中的數(shù)據(jù)類(lèi)型在pandas中依然適用
- 核心數(shù)據(jù)結(jié)構(gòu)
-
Series
:一維、帶有索引、同類(lèi)型元素的數(shù)組,與Numpy
中的一維array類(lèi)似; -
DateFrame
:二維、帶有索引、大小可變、可以不同類(lèi)型元素的表格數(shù)據(jù),可以看作是Series的容器,即一個(gè)DateFrame
可以包含若干個(gè)Series
。
第3章 創(chuàng)建對(duì)象
-
Series
:標(biāo)量值列表,默認(rèn)索引為整數(shù);pd.Series([1, 3, 5, np.nan, 6, 8]) 0 1.0 1 3.0 2 5.0 3 NaN 4 6.0 5 8.0 dtype: float64
-
Dataframe
:帶有日期時(shí)間的索引、Numpy數(shù)組;dates = pd.date_range('2018-07-10', periods=6) dates -- > DatetimeIndex(['2018-07-10', '2018-07-11', '2018-07-12', '2018-07-13','2018-07-14', '2018-07-15'], dtype='datetime64[ns]', freq='D') df = pd.DataFrame(np.random.randn(6, 4), index=dates, columns=list('ABCD')) print(df) A B C D 2018-07-10 -0.710755 -0.757183 0.809279 -0.718210 2018-07-11 -1.508561 -0.173393 0.815395 -1.242897 2018-07-12 -2.157823 -0.462607 -0.915480 2.595037 2018-07-13 0.826433 -0.216765 -1.636825 -0.671588 2018-07-14 -0.438337 0.270277 -1.208112 1.982913 2018-07-15 0.863050 0.442406 0.871964 1.107883
-
Dataframe
:可以轉(zhuǎn)換為類(lèi)似Series系列的dict對(duì)象;df2 = pd.DataFrame({ 'A':1., 'B':pd.Timestamp('20180710'), 'C':pd.Series(1, index=list(range(4)), dtype='float32'), 'D':np.array([2]*4, dtype='int32'), 'E':np.array([1, 2, 3, 4], dtype='int64'), 'F':pd.Categorical(['test', 'learn', 'test', 'learn']), 'G':'xz' }) print(df2) A B C D E F G 0 1.0 2018-07-10 1.0 2 1 test xz 1 1.0 2018-07-10 1.0 2 2 learn xz 2 1.0 2018-07-10 1.0 2 3 test xz 3 1.0 2018-07-10 1.0 2 4 learn xz
- DataFrame的不同列,具有不同的
dtypes
。print(df2.dtypes) A float64 B datetime64[ns] C float32 D int32 E int64 F category G object dtype: object
第4章 查看數(shù)據(jù)
-
head(x)
查看頂行數(shù)據(jù)、tail(x)
查看底行數(shù)據(jù),x
表示查看的行數(shù),默認(rèn)為5;df2.head(2) #查看頂部2行數(shù)據(jù) A B C D E F G 0 1 2018-07-10 1 2 1 test xz 1 1 2018-07-10 1 2 2 learn xz df2.tail(3) # 查看底部3行數(shù)據(jù) A B C D E F G 1 1 2018-07-10 1 2 2 learn xz 2 1 2018-07-10 1 2 3 test xz 3 1 2018-07-10 1 2 4 learn xz
- 查看索引、列名稱(chēng)、基礎(chǔ)Numpy數(shù)據(jù);
df2.index -- > Int64Index([0, 1, 2, 3], dtype='int64') df2.columns -- > Index(['A', 'B', 'C', 'D', 'E', 'F', 'G'], dtype='object') df2.values array([[1.0, Timestamp('2018-07-10 00:00:00'), 1.0, 2, 1, 'test', 'xz'], [1.0, Timestamp('2018-07-10 00:00:00'), 1.0, 2, 2, 'learn', 'xz'], [1.0, Timestamp('2018-07-10 00:00:00'), 1.0, 2, 3, 'test', 'xz'], [1.0, Timestamp('2018-07-10 00:00:00'), 1.0, 2, 4, 'learn', 'xz']], dtype=object)
- 描述性統(tǒng)計(jì);
df.describe() A B C D count 6.000000 6.000000 6.000000 6.000000 mean -0.203846 -0.520712 0.252811 0.056574 std 1.824972 0.629551 1.047736 0.535639 min -2.441260 -1.616401 -0.849088 -0.795480 25% -1.805976 -0.669989 -0.564042 -0.165330 50% 0.214104 -0.472665 0.257587 0.142493 75% 1.160094 -0.065817 0.595098 0.291087 max 1.793887 0.103427 1.981094 0.777256
- 轉(zhuǎn)置數(shù)據(jù)
df2.T 0 1 2 3 A 1 1 1 1 B 2018-07-10 00:00:00 2018-07-10 00:00:00 2018-07-10 00:00:00 2018-07-10 00:00:00 C 1 1 1 1 D 2 2 2 2 E 1 2 3 4 F test learn test learn G xz xz xz xz
第5章 選取數(shù)據(jù)
- 獲取一列,即Series
df.A # 等同于 df['A'] 2018-07-10 -0.177312 2018-07-11 -2.441260 2018-07-12 -2.348864 2018-07-13 0.605520 2018-07-14 1.344952 2018-07-15 1.793887 Freq: D, Name: A, dtype: float64
- 行切片:索引或值
df[:3] # 索引切片 A B C D 2018-07-10 -0.710755 -0.757183 0.809279 -0.718210 2018-07-11 -1.508561 -0.173393 0.815395 -1.242897 2018-07-12 -2.157823 -0.462607 -0.915480 2.595037 df['2018-07-11':'2018-07-14'] # 值切片 A B C D 2018-07-11 -1.508561 -0.173393 0.815395 -1.242897 2018-07-12 -2.157823 -0.462607 -0.915480 2.595037 2018-07-13 0.826433 -0.216765 -1.636825 -0.671588 2018-07-14 -0.438337 0.270277 -1.208112 1.982913
- 函數(shù):
loc[]、iloc[]
-
loc[]
:根據(jù)行或列的索引值,獲取數(shù)據(jù),含下限
,可僅取行或列; -
iloc[]
:根據(jù)行或列的索引位置,獲取數(shù)據(jù),不含下限
,可僅取行或列; -
僅取一行
df.loc['2018-07-11'] 等同于 df.iloc[1] A -1.508561 B -0.173393 C 0.815395 D -1.242897 Name: 2018-07-11 00:00:00, dtype: float64
-
僅取一列
df.loc[:,'C'] 等同于 df.iloc[:,2] 2018-07-10 0.809279 2018-07-11 0.815395 2018-07-12 -0.915480 2018-07-13 -1.636825 2018-07-14 -1.208112 2018-07-15 0.871964 Freq: D, Name: C, dtype: float64
-
行列連續(xù)截取
df.loc['2018-07-12':'2018-07-14',['B', 'C', 'D']] 等同于 df.iloc[2:5, 1:4] B C D 2018-07-12 -0.462607 -0.915480 2.595037 2018-07-13 -0.216765 -1.636825 -0.671588 2018-07-14 0.270277 -1.208112 1.982913 說(shuō)明:loc[]在選取行索引值時(shí),可以類(lèi)似切片的形式,但是在選取列索引時(shí),只能一個(gè)一個(gè)列舉,不能像類(lèi)似切片的形式用冒號(hào)連接取連續(xù)的中間值。
-
行列不連續(xù)截取
df.iloc[[0,5],[0,3]] # iloc[]行列均可以不連續(xù)截取數(shù)據(jù) A D 2018-07-10 -0.710755 -0.718210 2018-07-15 0.863050 1.107883 df.loc['2017-07-10':'2018-07-15', ['A', 'D']] # loc[]行索引 不 可以不連續(xù)截取 A D 2018-07-10 -0.710755 -0.718210 2018-07-11 -1.508561 -1.242897 2018-07-12 -2.157823 2.595037 2018-07-13 0.826433 -0.671588 2018-07-14 -0.438337 1.982913 2018-07-15 0.863050 1.107883
-
獲取單個(gè)值
df.loc['2018-07-14', 'C'] 等同于 df.iloc[4,2] -1.2081117496772031
-
補(bǔ)充:
loc[]、iloc[]
方法也可以對(duì)DataFrame進(jìn)行賦值等操作。
- 布爾判斷:多列值判斷時(shí),
&
表示and的關(guān)系,|
表示or的關(guān)系df[df.C < 0.5] #單個(gè)列值判斷 A B C D 2018-07-12 -2.157823 -0.462607 -0.915480 2.595037 2018-07-13 0.826433 -0.216765 -1.636825 -0.671588 2018-07-14 -0.438337 0.270277 -1.208112 1.982913 df[(df.A < 0) & (df.D > 0)] A B C D 2018-07-12 -2.157823 -0.462607 -0.915480 2.595037 2018-07-14 -0.438337 0.270277 -1.208112 1.982913 df[df > 0] #DataFrame值判斷 A B C D 2018-07-10 NaN NaN 0.809279 NaN 2018-07-11 NaN NaN 0.815395 NaN 2018-07-12 NaN NaN NaN 2.595037 2018-07-13 0.826433 NaN NaN NaN 2018-07-14 NaN 0.270277 NaN 1.982913 2018-07-15 0.863050 0.442406 0.871964 1.107883
- 過(guò)濾函數(shù):
isin()
df2 = df.copy() df2['E'] = ['one', 'two', 'three', 'four', 'five', 'six'] print(df2) A B C D E 2018-07-10 -0.710755 -0.757183 0.809279 -0.718210 one 2018-07-11 -1.508561 -0.173393 0.815395 -1.242897 two 2018-07-12 -2.157823 -0.462607 -0.915480 2.595037 three 2018-07-13 0.826433 -0.216765 -1.636825 -0.671588 four 2018-07-14 -0.438337 0.270277 -1.208112 1.982913 five 2018-07-15 0.863050 0.442406 0.871964 1.107883 six df2[df2.E.isin(['two', 'five'])] A B C D E 2018-07-11 -1.508561 -0.173393 0.815395 -1.242897 two 2018-07-14 -0.438337 0.270277 -1.208112 1.982913 five
- 模糊匹配:
contains()
df2[df2.E.str.contains('o')] # 選取E列中含有關(guān)鍵字“o”的數(shù)據(jù) A B C D E 2018-07-10 -1.738617 -1.013051 -1.938631 -1.049786 one 2018-07-11 -0.719089 -1.042707 -0.616299 0.460417 two 2018-07-13 -0.446243 -2.036736 1.469567 0.256282 four
- 獲取數(shù)據(jù)的方法,同樣可以對(duì)DataFrame進(jìn)行重新賦值。
第6章 缺失值
- Pandas使用
np.nan
來(lái)表示缺失的數(shù)據(jù),默認(rèn)不包含在計(jì)算中; - 準(zhǔn)備數(shù)據(jù)
df3 = df.reindex(index=dates[0:4], columns=list(df.columns) + ['E']) # 增加索引,默認(rèn)數(shù)據(jù)均為空 df3.iloc[0:2, 4] = 1 # 賦值 print(df3) A B C D E 2018-07-10 -0.177312 -0.456757 -0.849088 0.107067 1 2018-07-11 -2.441260 -0.730461 1.981094 0.177919 1 2018-07-12 -2.348864 0.103427 0.607445 -0.795480 NaN 2018-07-13 0.605520 -0.488574 0.558058 0.328810 NaN
- 刪除任何缺少數(shù)據(jù)的行
df3.dropna(how='any') # axis=1時(shí)刪除列數(shù)據(jù)、how=all時(shí)所有值均為空時(shí)才刪除 A B C D E 2018-07-10 -0.710755 -0.757183 0.809279 -0.718210 1.0 2018-07-11 -1.508561 -0.173393 0.815395 -1.242897 1.0
- 替換缺失值
df3.fillna(1000) #將空值替換為1000 A B C D E 2018-07-10 -0.710755 -0.757183 0.809279 -0.718210 1.0 2018-07-11 -1.508561 -0.173393 0.815395 -1.242897 1.0 2018-07-12 -2.157823 -0.462607 -0.915480 2.595037 1000.0 2018-07-13 0.826433 -0.216765 -1.636825 -0.671588 1000.0
- 判斷缺失值
pd.isna(df3) # 不同的pandas版本,可以用isnull() A B C D E 2018-07-10 False False False False False 2018-07-11 False False False False False 2018-07-12 False False False False True 2018-07-13 False False False False True
第7章 排序
- 按索引排序
- 語(yǔ)法:
sort_index(axis=0/1, ascengding=True/False)
- axis缺失或?yàn)?時(shí),按行索引排序,為1時(shí)按列索引(columns)排序;
- ascengding缺失或?yàn)門(mén)rue時(shí),表示升序,為False時(shí)表示降序;
- 示例
df3.sort_index(axis=1, ascending=False) #列排序,降序 E D C B A 2018-07-10 1.0 -0.718210 0.809279 -0.757183 -0.710755 2018-07-11 1.0 -1.242897 0.815395 -0.173393 -1.508561 2018-07-12 NaN 2.595037 -0.915480 -0.462607 -2.157823 2018-07-13 NaN -0.671588 -1.636825 -0.216765 0.826433
- 按值排序
- 語(yǔ)法:
sort_values(by='colums_name', ascengding=True/False)
- 示例
df3.sort_values(by=['D', 'C'], ascending=False) A B C D E 2018-07-12 -2.157823 -0.462607 -0.915480 2.595037 NaN 2018-07-13 0.826433 -0.216765 -1.636825 -0.671588 NaN 2018-07-10 -0.710755 -0.757183 0.809279 -0.718210 1.0 2018-07-11 -1.508561 -0.173393 0.815395 -1.242897 1.0
- 自定義排序
- 步驟
- 第一步:將需要自定義排序的字段,設(shè)置為“category”數(shù)據(jù)類(lèi)型
- 第二步:對(duì)字段進(jìn)行自定義排序
- 第三步:對(duì)DataFrame進(jìn)行排序
- 準(zhǔn)備數(shù)據(jù)
df_sort = pd.DataFrame({ "word":['a', 'b', 'c'], "number":[1, 2, 3]}) print(df_sort) word number 0 a 1 1 b 2 2 c 3 # 需要排列的順序 sort_column = ['c', 'b', 'a']
- 示例
df_sort.word = df.word.astype('category') #把排序字段設(shè)置為"category"類(lèi)型 df_sort.word.cat.reorder_categories(sort_column, inplace=True) # 字段按自定義排序 df_sort.sort_values('word',inplace=True) # DataFrame按自定義排序 print(df_sort) word number 2 c 3 1 b 2 0 a 1
第8章 常用操作
- 統(tǒng)計(jì):
mean(x)
、count(x)
、min(x)
、max(x)
、std(x)
等,x
為0時(shí)是行操作、x
為1時(shí)是列操作。統(tǒng)計(jì)時(shí)上述函數(shù)會(huì)忽略缺失值。df3.mean() #統(tǒng)計(jì)每列的均值 A -0.887676 B -0.402487 C -0.231908 D -0.009415 E 1.000000 dtype: float64 df3.max(1) #統(tǒng)計(jì)每行的最大值 2018-07-10 1.000000 2018-07-11 1.000000 2018-07-12 2.595037 2018-07-13 0.826433 Freq: D, dtype: float64
- 函數(shù):
apply()
df3.apply(np.cumsum) #統(tǒng)計(jì)每列的累加和 A B C D E 2018-07-10 -0.710755 -0.757183 0.809279 -0.718210 1.0 2018-07-11 -2.219316 -0.930576 1.624674 -1.961108 2.0 2018-07-12 -4.377138 -1.393183 0.709194 0.633930 NaN 2018-07-13 -3.550705 -1.609948 -0.927632 -0.037658 NaN df3.apply(lambda x: x.max() - x.min(), axis=1) #統(tǒng)計(jì)每行最大值與最小值之差 2018-07-10 1.757183 2018-07-11 2.508561 2018-07-12 4.752860 2018-07-13 2.463258 Freq: D, dtype: float64
- 求和、不同值計(jì)數(shù)
np.sum(df3.C) # 對(duì)C列求和 -0.927631569447292 df3.E.value_counts() # 對(duì)E列不同值計(jì)數(shù),自動(dòng)忽略空值 1.0 2 Name: E, dtype: int64
- 字符串方法
str
df4 = pd.DataFrame({"A":['foo', 'bar', 'bar', 'xz'], "B":['one', 'two', 'one', 'two'], "C":['Small', 'Small', 'Large', 'Large'], "D":[1, 2, 3, 4]}) print(df4) A B C D 0 foo one Small 1 1 bar two Small 2 2 bar one Large 3 3 xz two Large 4 df4.C.str.lower() # 字符串轉(zhuǎn)換為 小寫(xiě) 0 small 1 small 2 large 3 large Name: C, dtype: object df4[df4.A.str.endswith('r')] #字符串結(jié)尾字符篩選 A B C D 1 bar two Small 2 2 bar one Large 3
第9章 合并
- 關(guān)聯(lián)
merge()
- 用法:通過(guò)
鍵
橫向拼接列
,類(lèi)似sql中的join,通過(guò)一個(gè)或多個(gè)
鍵將不同的DataFrame關(guān)聯(lián) - 參數(shù)說(shuō)明
-
how : inner、outer、left、right
關(guān)聯(lián)方式 -
on : [key1, key2......]
同字段名關(guān)聯(lián) -
left_on / right_on 、 left_key / right_key、left_index / right_index
不同字段名關(guān)聯(lián) - left_index / right_index = True時(shí),表示按索引進(jìn)行匹配
-
- 多對(duì)多關(guān)聯(lián)
left = pd.DataFrame({'key':['xz', 'xz'], 'value':[1, 2]}) print(left) key value 0 xz 1 1 xz 2 right = pd.DataFrame({'key':['xz', 'xz'], 'value':[5, 6]}) print(right) key value 0 xz 5 1 xz 6 join = pd.merge(left, right, on='key') #多對(duì)多關(guān)聯(lián) print(join) key value_x value_y 0 xz 1 5 1 xz 1 6 2 xz 2 5 3 xz 2 6
- 一對(duì)一關(guān)聯(lián)
left = pd.DataFrame({'key':['xz', 'ab'], 'value':[1, 2]}) print(left) key value 0 xz 1 1 ab 2 right = pd.DataFrame({'key':['xz', 'ab'], 'value':[5, 6]}) print(right) key value 0 xz 5 1 ab 6 join = pd.merge(left, right, on='key') # 一對(duì)一關(guān)聯(lián) print(join) key value_x value_y 0 xz 1 5 1 ab 2 6
- 追加
append()
- 用法:
縱向
追加數(shù)據(jù),橫向同時(shí)擴(kuò)充,不考慮columns和index,數(shù)據(jù)列不一樣時(shí),設(shè)置ignore_index = True
; - 示例
df5 = pd.DataFrame(np.random.randint(10, 20, [2,4]),columns=list('ABCD')) print(df5) A B C D 0 19 16 15 15 1 16 15 16 10 s = df5[1:] print(s) A B C D 1 16 15 16 10 df5.append(s, ignore_index=True) # ignore_index:默認(rèn)為False, 若為T(mén)rue,表示不要使用索引標(biāo)簽 A B C D 0 19 16 15 15 1 16 15 16 10 2 16 15 16 10
- 拼接
concat()
- 用法:?jiǎn)渭兊谋砥唇樱梢?code>橫向或
縱向
,可以一次性拼接多個(gè)表,結(jié)果不去重復(fù),需要指定軸進(jìn)行連接,drop_duplicates()可以去重復(fù)。 - 參數(shù)說(shuō)明
-
objs
:連接對(duì)象,如:Series、DataFrame、list -
axis
= 0 時(shí),與append()
方法相同;axis
= 1時(shí),與merge()
方法相同 -
join
:inner、outer(默認(rèn)) -
join_axes
:設(shè)置需要保留的表索引 -
ignore_index
:是否忽略原索引 -
keys
:為原連接對(duì)象添加一個(gè)鍵,便于后期分組統(tǒng)計(jì)
-
- 示例
df6 = pd.DataFrame(np.random.randn(8, 4)) print(df6) 0 1 2 3 0 1.259128 1.352209 0.934947 0.734223 1 -0.567591 -1.114880 -1.540007 0.192176 2 1.007433 0.774980 1.229243 1.413190 3 1.029385 0.316052 0.363644 1.310764 4 -0.414858 2.030369 1.910180 -0.785533 5 0.684923 -0.064547 -1.475371 -0.842338 6 -0.289478 2.119747 0.519206 -2.564895 7 0.958962 -1.278468 0.099762 0.226029 pd.concat([df6[:2], df6[3:5], df6[7:]], keys=['x', 'y', 'z']) 0 1 2 3 x 0 1.259128 1.352209 0.934947 0.734223 1 -0.567591 -1.114880 -1.540007 0.192176 y 3 1.029385 0.316052 0.363644 1.310764 4 -0.414858 2.030369 1.910180 -0.785533 z 7 0.958962 -1.278468 0.099762 0.226029
- 合并
join()
- 用法:默認(rèn)以
index
為拼接列,其參數(shù)與merge方法基本一致,默認(rèn) how = left ,可以合并相同或相似的索引,目前已較少使用。
第10章 分組
-
單列分組--單列運(yùn)算
df7 = pd.DataFrame({'A': list('XYZXYZXYZX'), 'B': [1, 2, 1, 3, 1, 2, 3, 3, 1, 2], 'C': [12, 14, 11, 12, 13, 14, 16, 12, 10, 19]}) print(df7) A B C 0 X 1 12 1 Y 2 14 2 Z 1 11 3 X 3 12 4 Y 1 13 5 Z 2 14 6 X 3 16 7 Y 3 12 8 Z 1 10 9 X 2 19 df7.groupby('A').C.mean() # 按A列分組,統(tǒng)計(jì)C列的均值 A X 14.750000 Y 13.000000 Z 11.666667 Name: C, dtype: float64
-
單列分組--單列多種運(yùn)算
df7.groupby('A').B.agg([np.mean,np.std]) mean std A X 2.250000 0.957427 Y 2.000000 1.000000 Z 1.333333 0.577350
-
單列分組--多列相同運(yùn)算
df7.groupby('A')['B', 'C'].mean() B C A X 2.250000 14.750000 Y 2.000000 13.000000 Z 1.333333 11.666667
-
單列分組--多列不同運(yùn)算
df7.groupby('A')['B', 'C'].agg({'B': 'count', 'C': 'sum'}) B C A X 4 59 Y 3 39 Z 3 35 說(shuō)明:在分組統(tǒng)計(jì)時(shí),一般的統(tǒng)計(jì)函數(shù)會(huì)自動(dòng)忽略空值,計(jì)數(shù)時(shí)使用`size()`函數(shù),會(huì)包含空值。
-
單列分組--多列多個(gè)不同運(yùn)算
df7.groupby('A').agg({'B':[np.mean, 'sum'], 'C':['count', np.std]}) B C mean sum count std A X 2.250000 9 4 3.403430 Y 2.000000 6 3 1.000000 Z 1.333333 4 3 2.081666
-
多列分組--單列運(yùn)算
df7.groupby(['A', 'B']).C.sum() A B X 1 12 2 19 3 28 Y 1 13 2 14 3 12 Z 1 21 2 14 說(shuō)明:多列分組后的各種運(yùn)算,和單列分組后一樣,不再舉例。
-
函數(shù)
apply()+lambda()
df7.groupby('A').apply(lambda x: (x['C'] - x['B']).mean()) # B列與C列之差的均值 A X 12.500000 Y 11.000000 Z 10.333333
函數(shù)
transform()
- 聚合運(yùn)算時(shí),通常輸出的結(jié)果是一個(gè)以分組名為 index 的結(jié)果對(duì)象,若需要使用原數(shù)組的 index ,即把聚合結(jié)果關(guān)聯(lián)到原數(shù)組對(duì)象時(shí),使用該函數(shù)。
- 示例
# 普通的分組 df7.groupby(['A', 'B']).C.count() A B X 1 1 2 1 3 2 Y 1 1 2 1 3 1 Z 1 2 2 1 df7['count'] = df7.groupby(['A', 'B']).C.transform('count') print(df7) A B C count 0 X 1 12 1 1 Y 2 14 1 2 Z 1 11 2 3 X 3 12 2 4 Y 1 13 1 5 Z 2 14 1 6 X 3 16 2 7 Y 3 12 1 8 Z 1 10 2 9 X 2 19 1
- 分段分組
- 分段函數(shù)
cut()
:將數(shù)據(jù)值分段,主要用于將連續(xù)變量轉(zhuǎn)換為分類(lèi)變量 -
等距離分段:數(shù)據(jù)中的最小值和最大值,左右側(cè)各擴(kuò)展0.1%,做為分段邊界;
df8 = pd.DataFrame({'Age': np.random.randint(20, 70, 15), 'Sex': np.random.choice(['Male', 'Female'], 15), 'num': np.random.randint(1, 20, 15)}) print(df8) Age Sex num 0 22 Male 6 1 49 Male 12 2 52 Female 13 3 29 Female 1 4 46 Male 18 5 64 Female 2 6 42 Male 9 7 33 Male 15 8 25 Male 16 9 38 Male 4 10 32 Male 8 11 28 Male 8 12 31 Male 8 13 62 Male 6 14 40 Male 13 pd.cut(df8['Age'], bins=3) #等距離分割 0 (21.958, 36.0] 1 (36.0, 50.0] 2 (50.0, 64.0] 3 (21.958, 36.0] 4 (36.0, 50.0] 5 (50.0, 64.0] 6 (36.0, 50.0] 7 (21.958, 36.0] 8 (21.958, 36.0] 9 (36.0, 50.0] 10 (21.958, 36.0] 11 (21.958, 36.0] 12 (21.958, 36.0] 13 (50.0, 64.0] 14 (36.0, 50.0] Name: Age, dtype: category Categories (3, interval[float64]): [(21.958, 36.0] < (36.0, 50.0] < (50.0, 64.0]] df8.groupby(pd.cut(df8['Age'], bins=3)).mean() # 等距分組 Age num Age (21.958, 36.0] 28.571429 8.857143 (36.0, 50.0] 43.000000 11.200000 (50.0, 64.0] 59.333333 7.000000
-
自定義范圍分段:范圍段可以不均勻
pd.cut(df8['Age'], bins=[0,30,50,np.inf]) #自定義范圍進(jìn)行分割,可以不均勻 0 (50.0, inf] 1 (0.0, 30.0] 2 (50.0, inf] 3 (0.0, 30.0] 4 (30.0, 50.0] 5 (50.0, inf] 6 (50.0, inf] 7 (30.0, 50.0] 8 (0.0, 30.0] 9 (30.0, 50.0] 10 (50.0, inf] 11 (0.0, 30.0] 12 (50.0, inf] 13 (30.0, 50.0] 14 (50.0, inf] Name: Age, dtype: category Categories (3, interval[float64]): [(0.0, 30.0] < (30.0, 50.0] < (50.0, inf]] # 自定義分段進(jìn)行分組統(tǒng)計(jì) df8.groupby(pd.cut(df8['Age'], bins=[0, 30, 50, np.inf])).mean() Age num Age (0.0, 30.0] 23.250000 8.250000 (30.0, 50.0] 37.000000 9.250000 (50.0, inf] 59.428571 10.428571
- 統(tǒng)計(jì)頻率
- 交叉表
crosstab()
:一種特殊的pivot_table(),主要于計(jì)算分段分組頻率; - 對(duì)指定列分段后,再進(jìn)行分組,經(jīng)常需要計(jì)算分組頻率;
- 對(duì)字段
Age
分段后,計(jì)算Sex
的分組頻率,即按 Age 的分組范圍和性別 Sex 進(jìn)行制作交叉表。pd.crosstab(pd.cut(df8.Age, bins=[0, 30, 50, np.inf]), df8.Sex) Sex Female Male Age (0.0, 30.0] 1 3 (30.0, 50.0] 0 8 (50.0, inf] 2 1
第11章 透視表
pivot_table()
- 參數(shù)說(shuō)明
param | instroduction |
---|---|
data | DataFrame |
value | 待聚合的列名稱(chēng),默認(rèn)聚合所有數(shù)據(jù)列 |
index | 用于分組的列名或其他分組鍵,出現(xiàn)在結(jié)果透視表的行
|
columns | 用于分組的列名或其他分組鍵,出現(xiàn)在結(jié)果透視表的列
|
aggfunc | 聚合函數(shù)或函數(shù)列表,默認(rèn)為mean 。可以使任何對(duì)groupby有效的函數(shù) |
fill_value | 用于替換結(jié)果表中的缺失值 |
dropna | boolean,默認(rèn)為T(mén)rue |
margins | 是否添加匯總的行列 |
margins_name | 默認(rèn)為all ,margins=True時(shí)設(shè)置匯總行列的名稱(chēng) |
-
準(zhǔn)備數(shù)據(jù)
df9 = 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, 3, 4, 3, 4, 5, 6, 7]}) print(df9) A B C D 0 foo one small 1 1 foo one large 2 2 foo one large 3 3 foo two small 4 4 foo two small 3 5 bar one large 4 6 bar one small 5 7 bar two small 6 8 bar two large 7
-
默認(rèn)聚合方法
pd.pivot_table(df9, index=['A', 'B'], columns='C', values='D') #默認(rèn)聚合函數(shù)為均值 C large small A B bar one 4.0 5.0 two 7.0 6.0 foo one 2.5 1.0 two NaN 3.5
- 設(shè)置聚合方法
# 設(shè)置單個(gè)聚合方法 pd.pivot_table(df9, index=['A', 'B'], columns='C', values='D', aggfunc=np.sum, fill_value=0) #求和、空值設(shè)置為0 C large small A B bar one 4 5 two 7 6 foo one 5 1 two 0 7 # 設(shè)置多個(gè)聚合方法 df9['E'] = [8, 9, 10, 11, 12, 13, 14, 15, 16] pd.pivot_table(df13, values=['D', 'E'], index=['A', 'C'], aggfunc={'D': np.mean, 'E': [min, max, np.median]}) D E mean max median min A C bar large 5.500000 16 14.5 13 small 5.500000 15 14.5 14 foo large 2.500000 10 9.5 9 small 2.666667 12 11.0 8
pivot()
- 透視后,不進(jìn)行統(tǒng)計(jì)處理,主要用來(lái)處理非數(shù)字?jǐn)?shù)據(jù),進(jìn)行行列轉(zhuǎn)換;
- 其
index
只能是一個(gè)指定的列,index
和columns
對(duì)應(yīng)的數(shù)據(jù)元組,不能有重復(fù),否則會(huì)報(bào)錯(cuò)。 - 準(zhǔn)備數(shù)據(jù)
df10 = pd.DataFrame({ "A": ["foo", "bar", "bar", "xz"], "B": ["one", "two", "one", "two"], "C": ["small", "large", "large", "small"], "D": [1, 2, 3, 4]}) print(df10) A B C D 0 foo one small 1 1 bar two large 2 2 bar one large 3 3 xz two small 4
- 示例
df10.pivot(index='A', columns='B', values='D') B one two A bar 3.0 2.0 foo 1.0 NaN xz NaN 4.0
第12章 其它
- 操作文件
- 以csv格式文件為例,讀取
read_csv()
、寫(xiě)入to_csv()
- 常見(jiàn)格式:excel、txt、sql、html、json等
- 常用操作
- 查看列的數(shù)據(jù)類(lèi)型:
df.dtypes
- 查看數(shù)據(jù)詳情:
df.info()
- 刪除A列 :
df.drop(A, axis = 1)
- 更改列名 :
df = df.rename(columns = {'old_name': 'new_name'})
- 替換值 :
df.replace(to_replace, values)
- 設(shè)置列數(shù)據(jù)類(lèi)型:
df.A = df.A.values.astype(‘float64’)
- 日期字符串轉(zhuǎn)date:
pd.to_datetime(df.date).dt.date
- 日期字符串轉(zhuǎn)時(shí)間戳:
pd.to_datetime(df.date).dt.to_pydatetime()
-
時(shí)間處理:
dt
- 用途:作用于
datetime64[ns]
/timedelta64[ns]
等日期型數(shù)據(jù),獲取datetimelike
屬性的Accessor
對(duì)象 - 設(shè)置日期格式 :
dt.strftime()
- 獲取日期中的信息:
dt.date
/dt.year
/dt.month
/dt.time
/dt.weekday
/dt.dayofyear
/dt.weekofyear
- 設(shè)置日期運(yùn)算單位 :
[datetime1 - datetime2].dt.days
-
合并列:
cat
- 語(yǔ)法:
df['A'].str.cat([df['B'], df['C']], sep='-')
- 合并的2列的內(nèi)容必須是字符串,如果是數(shù)值型則會(huì)報(bào)錯(cuò),需要先轉(zhuǎn)換類(lèi)型;
- 當(dāng)需要將某列的內(nèi)容都加上一個(gè)指定字符時(shí),可以先創(chuàng)建一個(gè)由該字符組成的臨時(shí)列,再合并。
-
DataFrame
四則運(yùn)算
-
add
: 加法運(yùn)算,舉例:DataFrame1
.add(DataFrame2
, fill_value=0) -
sub
: 減法運(yùn)算,舉例:DataFrame1
.sub(DataFrame2
, fill_value=0) -
mul
: 乘法運(yùn)算,舉例:DataFrame1
.mul(DataFrame2
) -
div
: 除法運(yùn)算,舉例:DataFrame1
.div(DataFrame2
) -
說(shuō)明
: 上述參數(shù)DataFrame2
可以是:Series、DataFrame、constant
,Series類(lèi)型的數(shù)據(jù),也有類(lèi)似如上的四則運(yùn)算。
- 設(shè)置顯示選項(xiàng) :
pandas.set_option(pat, value)
- 保留小數(shù)點(diǎn)后的n位數(shù):
("precision", n)
- 展示n列:
("max_columns", n)
- 展示n行:
("max_rows", n)
- 絕對(duì)值小于n的顯示為0:
("chop_threshold", n)
- pd.options.mode.chained_assignment = None :關(guān)閉掉copywarning
- pd.options.display.max_columns = 999 :設(shè)置顯示的列數(shù)
- 常見(jiàn)的小坑
- 空
DataFrame
合并一個(gè)Series
時(shí),會(huì)重新排列生成的列順序,默認(rèn)按字母順序。特別是,使用loc[]
或iloc[]
選取的Series
,建議,先to_frame().T
轉(zhuǎn)成DataFrame
后再合并 - 列中類(lèi)似:date、datetime、time型的字符串?dāng)?shù)據(jù),需要轉(zhuǎn)為
datetime64[ns]
日期數(shù)據(jù),如df.date = pd.to_datetime(df.date)
,才能進(jìn)行選取:df[df.date == '2018-11-11']
- 列中
datetime64[ns]
日期數(shù)據(jù),進(jìn)行大小判斷選取數(shù)據(jù)時(shí),與空值比較,結(jié)果為空; - 數(shù)據(jù)列中存在空數(shù)據(jù)
NaN
,使用astype()
對(duì)其數(shù)據(jù)類(lèi)型進(jìn)行轉(zhuǎn)化時(shí),需要先將空數(shù)據(jù)NaN
排除掉,否則函數(shù)不起作用。其參數(shù)errors
只是對(duì)無(wú)法進(jìn)行轉(zhuǎn)換類(lèi)型的數(shù)據(jù)(非空)進(jìn)行處理; - 對(duì)
df[df.condition] = value
,即重新賦值時(shí),會(huì)報(bào)警,解決辦法:需要重新copy()一份,即df[df.condition].copy()后,再賦值。
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead
- groupby分組后,需要統(tǒng)計(jì)的字段較多且有條件判斷時(shí),使用apply() + lambda + pd.Series()來(lái)快速實(shí)現(xiàn);
- 在pandas中,沒(méi)有isnotin函數(shù),可以通過(guò)取反的方式實(shí)現(xiàn),取反的方法就是在函數(shù)前面加個(gè)
~
。例如:~(df.A == 4) ,等效于 df.A != 4。