整理歸納在Python中使用對(duì)數(shù)據(jù)處理的常用方法凭疮,包括與HDFS文件的讀寫领炫,主要是怕用的時(shí)候記不住西壮,容易搞混遗增,再搜也不爽,好記性不如爛筆頭款青,寫下來(lái)自己用的時(shí)候方便看做修,而且寫一遍也加深印象。
隨查隨用隨更新
Numpy
ndarray
ndarr1 = np.array([ [1, 2, 3], [4, 5, 6] ])
shape 大小和形狀
dtype 數(shù)據(jù)類型
astype 顯式的轉(zhuǎn)換類型
不同大小的ndarray也可以運(yùn)算抡草,稱之為廣播饰及,比如arr * 2
一維:用[x]進(jìn)行索引,用[x:y]進(jìn)行切片康震,都是原始數(shù)組的視圖
多維:[x][y]或者[x,y]索引燎含,[x1:x2, y1:y2]切片。
布爾型可以直接做索引
按軸進(jìn)行布爾類型list的索引腿短,或者對(duì)每個(gè)元素進(jìn)行單個(gè)布爾索引屏箍,比如data1[data1 > 0] = 0
花式索引行和列
arr[ [行1, 行i] ][ :, [列1, 列i] ] 或者
arr[ np.ix_( [行1, 行i], [列1, 列i] ) ]
而且花式索引總是復(fù)制數(shù)據(jù)到新的數(shù)組中,不是切片那種原始數(shù)組的視圖
arr.T 轉(zhuǎn)置
通用函數(shù)
np.sqrt(arr) arr的開平方
np.exp(arr) arr的e的x次方
np.abs(arr) arr的絕對(duì)值
np.square(arr) arr的平方
np.log(arr) ln(arr)
np.log10(arr) log10(arr)
np.isnan arr的各個(gè)元素是否為NaN的bool數(shù)組
np.add(arr1, arr2) arr1 + arr2
np.subtract(arr1, arr2) arr1 - arr2
三元表達(dá)式
np.where(cond, xarr, yarr) 等價(jià)為 xarr if cond else yarr
統(tǒng)計(jì)
arr.sum(axis=橘忱?) 按照軸的方向求和
arr.mean 按照軸的方向求平均值
arr.min()和max() 最大和最小值
arr.argmin()和argmax() 最大和最小值的索引
arr.cumsum() 所有元素的累計(jì)和
arr.cumprod() 所有元素的累計(jì)積
排序
np.sort(arr)和arr.sort()赴魁,前者是頂級(jí)方法,返回對(duì)arr排序后的副本钝诚;后者則是直接對(duì)arr排序尚粘。
線性代數(shù)
包括矩陣的點(diǎn)乘,矩陣分解以及行列式等等敲长。
點(diǎn)乘:xarr.dot(yarr)等價(jià)于np.dot(xarr, yarr)
numpy.linalg中有一組標(biāo)準(zhǔn)的矩陣分解運(yùn)算以及諸如求逆和行列式之類郎嫁。比如如下部分:
diag([一維數(shù)組]) 對(duì)角矩陣秉继,對(duì)角線是輸入的一維數(shù)組
dot 點(diǎn)乘
det 計(jì)算矩陣的行列式
inv 計(jì)算矩陣的逆
qr 計(jì)算QR分解
svd 計(jì)算奇異值分解(SVD)
Pandas
(官網(wǎng))https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.html
官網(wǎng)Pandas的API匯總
官網(wǎng)10分鐘對(duì)Pandas的簡(jiǎn)介
Series
可以把Series看成是一個(gè)有序的定長(zhǎng)字典。
ser = Series([1, 2, 3, 4], index=['d', 'b', 'a', 'c'])
經(jīng)常存在與DataFrame的行與列中泽铛。
也可以直接從字典類型的對(duì)象中構(gòu)建尚辑。
idx_val_map = {'d':1, 'b':2, 'a':3, 'c':4}
ser = Series(idx_val_map, name='值的名稱')
ser.index.name = '索引的名稱'
ser['a']進(jìn)行索引
再進(jìn)一步,比如對(duì)于二維的DataFrame盔腔,取其中一列出來(lái)杠茬,就是Series,它的name就是這一列的名字弛随,它的index就是DataFrame的index瓢喉,index的name就是DataFrame中作為index的那一列的名字。
DataFrame
DataFrame的索引是不可更改的舀透∷ㄆ保可以添加和刪除,但是不能修改愕够。
- 構(gòu)造DataFrame
1.由二維ndarray構(gòu)造走贪,可以給出行標(biāo)和列標(biāo)
2.由字典構(gòu)成,外層字典key是列標(biāo)惑芭,內(nèi)層字典是行標(biāo)result1 = pd.DataFrame([[1, 0.7], [0, 0.7]], index=pd.Index([135, 136], name='Number'), columns=['Gender', 'Prob'])
需要注意的是字典構(gòu)成的df坠狡,需要指定column的順序,否則默認(rèn)會(huì)按照列的字符串名排序
predict_df = pd.DataFrame(data={'svc_y': svc_y, 'dnn_y': dnn_y, 'xgb_y': xgb_y, 'rf_y': rf_y}, columns=['svc_y', 'dnn_y', 'xgb_y' ,'rf_y'])
3.由另一個(gè)DataFrame構(gòu)成
有時(shí)候會(huì)有一種需求是從已經(jīng)有的DataFrame中創(chuàng)建一個(gè)空的Dataframe但是使用的是原來(lái)這個(gè)Dataframe的結(jié)構(gòu)遂跟。
copy_df = pd.DataFrame.from_items([(name, pd.Series(data=None, dtype=series.dtype))
for name, series in original_df.iteritems()])
-
添加列
frame['new-col'] = value # 需要添加多列時(shí)比較特殊點(diǎn)需要借Dataframe來(lái)賦值 frame[['new-col1', ..., 'new-coln']] = pd.Dataframe(np.random.randint(1,5,[n_rows, n]), index=frame.index)
-
添加行
s = pd.Series({'Col1':'Value1', 'Col2': 'Value2', 'Col3': Value3}) # 構(gòu)造一行新數(shù)據(jù) frame.append(s)
-
刪除列
del frame['col-name']
-
刪除行
# 因?yàn)镈ataFrame是列索引的(在frame.items()返回值中可以看出來(lái))所以del只能刪除列逃沿,刪除行需要用到drop方法 frame.drop(frame.index[[1,3]])
-
索引方式
列索引:frame['col_name']或者frame.col_name
行索引:frame.ix['row_name']
點(diǎn)索引:frame.at[行,列] 或者frame.iat[行i幻锁,列i]感挥,只能索引具體的元素,不能切片
用整數(shù)位置索引frame.iloc[index(列表), col-index(列表)]
ix[行, 列]和iloc[行, 列]都可同時(shí)索引行與列越败,區(qū)別在于ix用的是名字(當(dāng)DataFrame的index沒(méi)有設(shè)置時(shí)触幼,退化成iloc),iloc用的是整數(shù)位置
loc: works on labels in the index.
iloc: works on the positions in the index (so it only takes integers).
ix: usually tries to behave like loc but falls back to behaving like iloc if the label is not in the index.- 總結(jié)
['col-name']——是對(duì)列的索引
[ ['col-name1', 'col-name_i'] ]——兩個(gè)[]是對(duì)多個(gè)列的索引
[bool類型list]或者[i:j]——是對(duì)行的切片索引
ix[行,列]——支持對(duì)行和列同時(shí)索引和切片(loc和iloc參考上面)NOTE:ix操作如果有左值究飞,那么就默認(rèn)會(huì)copy置谦,如果沒(méi)有左值那么就是對(duì)原始Frame進(jìn)行操作,而loc和iloc默認(rèn)都是對(duì)原始Frame的操作亿傅,所以推薦使用loc媒峡,如果需要復(fù)制,可以顯式的調(diào)用Frame.copy(). 不過(guò)仍要注意的是frame2 = frame1.loc[a:d, :]確實(shí)不是復(fù)制是對(duì)原frame1的切片葵擎,但是frame1.loc[ [a, b, c, d], :]則是復(fù)制不是切片了谅阿。
at[行,列]和iat[i,j]——是定位到元素
所以對(duì)列的bool類型list切片應(yīng)該用ix[:,bool_list],然而對(duì)行的bool類型list切片可以直接[bool_list]
- 總結(jié)
-
基本功能
重新索引
reindex,對(duì)索引重新排序签餐,新加的使用缺失值填充寓涨。丟棄指定軸上的項(xiàng)
frame.drop(['name'], axis=?)切片
frame[:2] 這個(gè)是直接按行切片,和常識(shí)有點(diǎn)不太一樣氯檐,但是方便實(shí)際操作戒良。
frame[ ['列1', '列i'] ]冠摄,這個(gè)是按列切片過(guò)濾
按照某一列的值過(guò)濾:frame[ frame['列'] > 5 ]
對(duì)于bool類型的list糯崎,除了上面的方法,也可以frame.loc[bool_list_X, bool_list_Y]進(jìn)行過(guò)濾河泳。算術(shù)運(yùn)算
frame1 + frame2 或者 frame1.add(frame2, fill_value=0)
sub做減法 div是除法 mul是乘法-
函數(shù)應(yīng)用和映射
Numpy的ufuncs也可用于操作pandas對(duì)象np.abs(frame)
還可以自定義函數(shù)(列或行的):
f = lambda x: x.max() - x.min()
frame.apply(f, axis=?)對(duì)元素的函數(shù)
format = lambda x: '%.2f' % x
frame.applymap(format)featQuant = sampleDF_feat.quantile(0.999) # 獲得0.999的分位數(shù)
frameFeatUnderQuant = sampleDF_feat.where(sampleDF_feat <= featQuant, other=0) # 把異常高的數(shù)值排除掉總的來(lái)說(shuō)沃呢,DataFrame可以用的是apply和applymap,Series可以用的是map:
apply:是對(duì)DataFrame的具體行或者列進(jìn)行整體操作拆挥。比如可以取最大最小值
applymap:是對(duì)DataFrame的具體每個(gè)元素進(jìn)行操作薄霜。
map:也是對(duì)每個(gè)元素進(jìn)行操作,和applymap類似竿刁。 排序
frame.sort_index(by='name', axis=?, ascending=True)
-
匯總和計(jì)算描述
frame.sum(axis=?, skipna=True) 求和
frame.mean() 平均值
frame.count()
frame.min黄锤、max
frame.argmin搪缨、argmax 整數(shù)索引位置
frame.idmin食拜、idmax 名字ID索引位置
frame.quantile() 計(jì)算樣本的分位數(shù)(0到1),比如frame['col_name'].quantile([q/10 for q in range(1, 11, 1)])
frame.describe() # 描述各個(gè)列的詳細(xì)統(tǒng)計(jì)信息
frame.info() # 描述各個(gè)列是否有缺失值和dtype
frame['col_name'].value_counts() # 計(jì)算得到col_name列上各種取值的個(gè)數(shù)- groupby
這個(gè)操作是對(duì)數(shù)據(jù)做聚合后的操作副编。
比如df['col1'].groupby(by=某種依據(jù))
负甸,就是在df的'col'列上按照某種依據(jù)來(lái)聚合,產(chǎn)生一個(gè)DataFrameGroupBy對(duì)象痹届。這里的某種依據(jù)就是告訴pandas在聚合時(shí)哪幾個(gè)數(shù)據(jù)屬于一類的呻待,比如df的行數(shù)為7,那么某種依據(jù)為['c','s','t','t','s','s','c']队腐,會(huì)把第一行和最后一行歸在一起蚕捉,第2\5\6行歸在一起,第3\4行歸在一起柴淘。
此時(shí)可以使用mean(),sum(),apply()這樣的操作來(lái)得到想要的值迫淹。當(dāng)對(duì)df['col1']做groupby時(shí)得到的每一項(xiàng)是Series,此時(shí)apply(lambda x: ...)中的x是Series類型为严;當(dāng)對(duì)df[['col1',...,'colN']]做groupby時(shí)得到的是Dataframe敛熬,此時(shí)apply(lambda x: ...)中的x是DataFrame類型。
比如對(duì)df['cnt']表示某個(gè)用戶購(gòu)買某個(gè)物品的個(gè)數(shù)第股,我們想得到每個(gè)用戶各自購(gòu)買物品占自己購(gòu)買總數(shù)的比值時(shí):df['cnt'].groupby(df['user_name']).apply(lambda cnts: cnts.apply(lambda n: n / cnts.sum()))
另外df.groupby(...).agg(func)
是指對(duì)df做group之后對(duì)每一列執(zhí)行func应民,如果不需要對(duì)每列執(zhí)行,則直接使用apply即可。agg的詳細(xì)示例見(jiàn):官網(wǎng)agg - melt
這個(gè)是讓df按照指定的列消融诲锹,比如df有3列繁仁,直接melt(),會(huì)得到新的melt_df由index, variable, value這三個(gè)列組成辕狰,其中index的范圍是原來(lái)的3倍改备,variable是原來(lái)的列名,value是原來(lái)對(duì)應(yīng)列的值蔓倍。
melt()函數(shù)有幾個(gè)參數(shù):id_vars='不消融的列', value_vars=消融的列l(wèi)ist, var_name='消融后variable的名字', value_name='消融后value的名字'
- groupby
-
處理缺失數(shù)據(jù)
frame.dropna() 丟棄NaN悬钳,可以給出閾值進(jìn)行調(diào)節(jié)容忍度
df.fillna( {'列1': 值1, '列i': 值i}, inplace=True ) 默認(rèn)返回一個(gè)新的對(duì)象
frame.isnull() 返回與frame一樣大小的布爾值對(duì)象(值為NaN的為True,否則為False) -
其他常用
# 去重 df.duplicated(keep='first') # 這個(gè)會(huì)返回列的值重復(fù)與否的布爾值偶翅,默認(rèn)對(duì)于重復(fù)值的第一個(gè)為False默勾,其他重復(fù)的為True # 得到這個(gè)布爾后可以再進(jìn)行切片去重,不過(guò)還有更便捷的方法: df['某列'].drop_duplicates(keep='first', inplace=True) # 這樣直接得到去重后的結(jié)果聚谁。
-
從文件中讀取
frame = pd.read_csv('file.csv', names=col_names, index_col='col_index')
另外說(shuō)下母剥,如果csv的文件中是這樣的0,1,2,"string:\"(1,2)\""
,那么上面在讀的過(guò)程中會(huì)有問(wèn)題形导,多讀出一列环疼,需要加上參數(shù)escapechar="\\"
,也就是:
frame = pd.read_csv('file.csv', names=col_names, index_col='col_index', escapechar="\\")
除了讀取本地文件還可以讀取HDFS文件:首先需要安裝需要的包:pip install hdfs 官網(wǎng)文檔
然后代碼中:from hdfs import Client from hdfs import HdfsError client = Client('http://name_node.url:50070') # 輸入要鏈接的NameNode地址朵耕。如果是高可用的模式炫隶,會(huì)有多個(gè)name node,那么有個(gè)比較笨的方法就是挨個(gè)試阎曹,看看那個(gè)可用(也就是處于active狀態(tài))就用哪個(gè)伪阶。 print(client.list('/')) # 可以在這里添加try操作,catch到異常后去嘗試下一個(gè)name node的鏈接处嫌。 try: with client.read('path/file.csv') as hdfs_in_fs: predictDF = pd.read_csv(hdfs_in_fs, names=predict_cols, index_col='Number') except HdfsError as e: print(e)
-
將Frame寫入文件
frame.to_csv(path_or_buf='path/file', index=True, header=False, sep='|')
寫入HDFS文件會(huì)有些麻煩栅贴,一是寫的時(shí)候需要權(quán)限,把要寫入的目錄設(shè)置為hdfs dfs -chmod -R 777 write_Dir
熏迹;二是寫入文件會(huì)遇到TypeError: a bytes-like object is required, not 'str'檐薯,因?yàn)椴幌衿胀ǖ奈募梢栽趏pen的時(shí)候設(shè)置mode參數(shù),所以還需要做如下操作:from hdfs import Client from hdfs import HdfsError client = Client('http://name_node.url:50070') # 輸入要鏈接的NameNode地址注暗。如果是高可用的模式坛缕,會(huì)有多個(gè)name node,那么有個(gè)比較笨的方法就是挨個(gè)試友存,看看那個(gè)可用(也就是處于active狀態(tài))就用哪個(gè)祷膳。 print(client.list('/')) # 可以在這里添加try操作,catch到異常后去嘗試下一個(gè)name node的鏈接屡立。 try: with client.write('path/file' overwrite=True, encoding='utf-8') as hdfs_out_fs: # 需要設(shè)置encoding不然遇到上面說(shuō)的TypeError predictDF[['Gender', 'Prob']].to_csv(path_or_buf=hdfs_out_fs, index=True, header=False, sep='|') except HdfsError as e: print(e)
-
另外一種讀寫HDFS文件的方法
上面的代碼確實(shí)可以讀寫HDFS文件直晨,不過(guò)需要修改權(quán)限搀军,這會(huì)出現(xiàn)下面情況:
這會(huì)給后續(xù)操作帶來(lái)一定的麻煩罩句,比如yarn用戶在程序中對(duì)這個(gè)文件無(wú)法修改。因?yàn)橹挥凶x權(quán)限敛摘。
不過(guò)還有一個(gè)API可以在python中使用门烂,如果你的HDFS配置支持非安全的HttpFS的話。上面的使用Client的API是用的WebHDFS兄淫。連接的時(shí)候需要指定namenode屯远,而在高可用的模式情況下,可能要多試幾次才知道當(dāng)前哪個(gè)node處于active狀態(tài)捕虽。為了避免這兩個(gè)問(wèn)題慨丐,接下來(lái)展示另外一個(gè)API InsecureClient來(lái)實(shí)現(xiàn)。在接下來(lái)的代碼中泄私,使用的是HttpFS方式來(lái)讀寫HDFS
from hdfs import InsecureClient client = InsecureClient('http://HttpFS_node.url:14000', user='yarn') # 使用HttpFS所配置的角色主機(jī)域名及REST 端口 print(client.list('/')) # 無(wú)需像之前一樣多次嘗試當(dāng)前輸入的namenode是否可用 with client.read('path/in_file') as hdfs_in_fs: with client.write('path/out_file', overwrite=True, encoding='utf-8') as hdfs_out_fs: sampleDF = pd.read_csv(hdfs_in_fs, names=, index_col=) sampleDF.to_csv(path_or_buf=hdfs_out_fs, index=True, header=False, sep='|')
這個(gè)API的好處是:1房揭、不需要修改權(quán)限,由參數(shù)的指定用戶保證權(quán)限沒(méi)問(wèn)題晌端。2捅暴、新寫入的文件權(quán)限也無(wú)問(wèn)題。3咧纠、可以支持遠(yuǎn)程讀寫蓬痒,無(wú)需在集群上執(zhí)行,在本地PC上運(yùn)行即可惧盹。4乳幸、無(wú)需知道當(dāng)前active的namenode是哪個(gè)瞪讼,可以通過(guò)HttpFS主機(jī)直接連接钧椰。
-
合并數(shù)據(jù)集
- pandas.merge
根據(jù)一個(gè)或多個(gè)鍵將不同的DataFrame中的行連接起來(lái)。類似SQL的關(guān)系型數(shù)據(jù)庫(kù)的連接操作
簡(jiǎn)單說(shuō)就是將多個(gè)DataFrame按照指定的各自的列以某種方式(inner符欠,left嫡霞,right,outer)組合起來(lái)希柿。
除了pd.merge還有frame_left.join(frame_right)這個(gè)方式
其中join和merge的區(qū)別如下:
left.join(right, on='col_name') #是將left的col_name列和right的index進(jìn)行比較連接,且默認(rèn)how='left' left.merge(right, on='col_name') #是將left和right共有的col_name列進(jìn)行比較連接,且默認(rèn)how='inner' # 不過(guò)如果right中如果沒(méi)有col_name列,那么還是會(huì)和join一樣會(huì)拿index來(lái)連接. # 另外merge還提供了left_on/right_on/left_index/right_index這些參數(shù)供選擇
- pandas.concat
沿著一條軸將多個(gè)對(duì)象堆疊在一起
比如將兩個(gè)frame的行數(shù)據(jù)堆疊起來(lái)诊沪。
frame_total = pd.concat([frame1, framei], axis=?, keys=['col1_name', 'coli_name']) - 舉栗
合并Series到Dataframe中:purchase_1 = pd.Series({'Name': 'Chris', 'Item Purchased': 'Dog Food', 'Cost': 22.50}) purchase_2 = pd.Series({'Name': 'Kevyn', 'Item Purchased': 'Kitty Litter', 'Cost': 2.50}) purchase_3 = pd.Series({'Name': 'Vinod', 'Item Purchased': 'Bird Seed', 'Cost': 5.00}) df = pd.DataFrame([purchase_1, purchase_2, purchase_3], index=['Store 1', 'Store 1', 'Store 2']) s = pd.Series({'Name':'Kevyn', 'Item Purchased': 'Kitty Food', 'Cost': 3.00}) s.name = 'Store 2' # 合并s到df中 # 方法1,使用concat函數(shù) df = pd.concat([df, s.to_frame().T]) # 方法2曾撤,使用append df = df.append(s)
- pandas.merge
-
打印DataFrame
打印DataFrame非常簡(jiǎn)單直接print就可以了端姚,但是Pandas對(duì)于顯示的行數(shù)、列數(shù)挤悉、寬度和長(zhǎng)度都有默認(rèn)限制渐裸,如果不期望看到...這樣的省略號(hào),或者不期望換行,那么可以如下設(shè)置:
在最近的pandas版本中昏鹃,已經(jīng)沒(méi)有display.height這個(gè)參數(shù)了尚氛,其值可由display.max_rows自動(dòng)推斷得到。pd.set_option('display.height',1000) # 把1000換成None即為無(wú)限制洞渤,下面均是如此阅嘶。 pd.set_option('display.max_rows',500) pd.set_option('display.max_columns',500) pd.set_option('display.width',1000)
上面的設(shè)置完之后會(huì)對(duì)后面的代碼全部做這個(gè)配置處理,如果想在代碼中動(dòng)態(tài)的改變载迄,還可以這么寫:
with pd.option_context('display.max_rows', None, 'display.max_columns', None, 'display.width', None): logging.info('輸出打印DataFrame:\n{}'.format(data_frame))
這樣在需要長(zhǎng)顯示的時(shí)候套上with就可以了讯柔,不需要的地方繼續(xù)使用pandas的默認(rèn)設(shè)置。
pandas的通用功能(官鏈)
pandas提供了很多general function來(lái)支持很多數(shù)據(jù)操作护昧。比如上面提到過(guò)的pandas.melt
還有其他經(jīng)常用到的pandas.concat, pandas.merge, pandas.unique
等磷杏,下面會(huì)介紹一些其他常用的功能:
pd.cut
我們有時(shí)會(huì)需要把連續(xù)數(shù)值轉(zhuǎn)換為類別,比如根據(jù)取值的大小按照某種分隔標(biāo)準(zhǔn)來(lái)劃分成類別捏卓。
更明確些极祸,我們可能有兩種劃分依據(jù),在pandas中均能找到對(duì)應(yīng)的函數(shù):1怠晴、按照取值來(lái)劃分遥金,比如某個(gè)特征取值從0到1,我們希望按照這個(gè)取值范圍分成3等份蒜田,那么就可以用pd.cut稿械;2、按照統(tǒng)計(jì)的個(gè)數(shù)來(lái)劃分冲粤,比如根據(jù)樣本在這個(gè)特征上的取值所統(tǒng)計(jì)的個(gè)數(shù)美莫,分為好中差三個(gè)等樣本個(gè)數(shù)的分類,這時(shí)可以用pd.qcut梯捕;
下面簡(jiǎn)單介紹下幾個(gè)常用參數(shù)
pd.cut(x=連續(xù)取值的數(shù)據(jù), bins=整數(shù)N(會(huì)自動(dòng)按照上下限的取值份N等份)/數(shù)組(會(huì)按照數(shù)組指示的間隔來(lái)劃分), labels=劃分后的標(biāo)記)
比如X的取值是0到1厢呵,希望按照(0, 0.25](0.25, 0.5](0.5, 0.75](0.75, 1]劃分成4份,且對(duì)應(yīng)的label分別是1到4:
pd.cut(X, bins=[i*1.0/4 for i in range(0, 4+1)], labels=range(1,4+1))
-
pd.qcut
介紹幾個(gè)常用的參數(shù)
pd.cut(x=連續(xù)取值的數(shù)據(jù), q=整數(shù)N(會(huì)自動(dòng)按照統(tǒng)計(jì)分位數(shù)分N等份)/數(shù)組(會(huì)按照數(shù)組指示的間隔來(lái)劃分), labels=劃分后的標(biāo)記)
比如q = [0, .25, .5, .75, 1.] for quartiles
pd.qcut(range(5), 3, labels=["good", "medium", "bad"])
... [good, good, medium, bad, bad] Categories (3, object): [good < medium < bad]
pd.get_dummies
這個(gè)是對(duì)類別特征做one-hot編碼傀顾,比如pd.get_dummies(df, columns=df.columns)
但是有個(gè)點(diǎn)需要注意下襟铭,比如現(xiàn)在有訓(xùn)練集和測(cè)試集,其中訓(xùn)練集中可能某個(gè)類別沒(méi)有在測(cè)試集中出現(xiàn)短曾,或者測(cè)試集中的某個(gè)類別沒(méi)有在訓(xùn)練集中出現(xiàn)寒砖。此時(shí)如果分別對(duì)它們做get_dummies就會(huì)出現(xiàn)得到的數(shù)據(jù)集的列對(duì)不起來(lái)。
此時(shí)需要做的是嫉拐,保證訓(xùn)練集中的列一定都會(huì)出現(xiàn)哩都,對(duì)于測(cè)試集中沒(méi)有包含訓(xùn)練集的列添加并值為0,對(duì)于測(cè)試集中含有訓(xùn)練集中沒(méi)有的去除婉徘,并保證兩個(gè)數(shù)據(jù)集的列順序一致漠嵌。
df_train_onehot = pd.get_dummies(train_df, columns=train_df.columns)
train_oh_cols = df_train_onehot.columns
df_test_onehot = pd.get_dummies(test_df, columns=test_df.columns)
test_oh_cols = df_test_onehot.columns
miss_cols = set(train_oh_cols) - set(test_oh_cols)
for col in miss_cols:
df_test_onehot[col] = 0
df_test_onehot = df_test_onehot[train_oh_cols]
除了上面這個(gè)做法外璃赡,還可以利用sklearn的OneHotEncoder來(lái)實(shí)現(xiàn)。
ohe = OneHotEncoder(sparse=False, handle_unknown='ignore')
然后在ohe.fit_transform(train_df)
接著ohe.transform(test_df)
即可献雅,不過(guò)ohe返回的值都是np.ndarray類型碉考,如果需要?jiǎng)t自己命名列的名字。
第一種方法要保存的是訓(xùn)練集的列名挺身,第二種方法則要把fit后的ohe模型保留下來(lái)侯谁。
Matplotlib
常用作圖方法
import matplotlib.pyplot as plt
%matplotlib inline # 在ipynb上顯示圖片
plt.plot([4, 3, 2, 1]) # 作圖代碼
plt.show() # 在python運(yùn)行程序時(shí)顯示
# 啟動(dòng)ipython作圖時(shí)可以: ipython --pylab,這樣就會(huì)自動(dòng)import matplotlib.pyplot as plt而且不用show()就可以輸出圖表章钾。
plt.plot([4, 3, 2, 1]) # 使用ipython --pylab后直接顯示圖圖表
直接用數(shù)據(jù)作圖
- 對(duì)于numpy的數(shù)組數(shù)據(jù)作圖:
fig = plt.figure()
ax1 = fig.add_subplot(2, 2, 1)
ax2 = fig.add_subplot(2, 2, 2)
ax3 = fig.add_subplot(2, 2, 3)
plt.plot([1.5, 3.5, -2, 1.6]) # 默認(rèn)對(duì)最后創(chuàng)建的subplot作圖
import numpy as np
from numpy.random import randn
_ = ax1.hist(randn(100), bins=20, color='k', alpha=0.3) # 直方圖
ax2.scatter(np.arange(30), np.arange(30) + 3 * randn(30)) # 散列圖
- 強(qiáng)調(diào)數(shù)據(jù)點(diǎn)
plt.plot(randn(30).cumsum(), 'ko--') # 等價(jià)于下面語(yǔ)句
plt.plot(randn(30).cumsum(), color='k', linestyle='dashed', marker='o')
- 圖中坐標(biāo)和標(biāo)題設(shè)置
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
ax.plot(randn(1000).cumsum())
ticks = ax.set_xticks([0, 250, 500, 750, 1000]) # 設(shè)置X軸的刻度
labels = ax.set_xticklabels(['one', 'two', 'three', 'four', 'five'], rotation=30, fontsize='small') # 刻度的標(biāo)簽
ax.set_title('My first matplotlib plot') # 圖的標(biāo)題
ax.set_xlabel('Stages') # X軸的名稱
- 添加圖例
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
ax.plot(randn(100).cumsum(), 'k', label='one') # 創(chuàng)建圖例
ax.plot(randn(100).cumsum(), 'g--', label='two')
ax.plot(randn(100).cumsum(), 'r.', label='three')
ax.legend(loc='best') # 把上面設(shè)置的圖例(legend)創(chuàng)建生效
- 保存圖表到文件
plt.savefig('figpath.svg')
plt.savefig('figpath.png', dpi=400, bbox_inches='tight')
Pandas的繪圖函數(shù)
- Series做柱狀圖
import pandas as pd
from pandas import Series, DataFrame
fig, axes = plt.subplots(nrows=2, ncols=1) # 獲得subplot集合
data = Series(np.random.rand(16), index=list('abcdefghijklmnop'))
data.plot(kind='bar', ax=axes[0], color='k', alpha=0.7) # 豎向柱狀圖,不設(shè)置kind默認(rèn)是線形圖
data.plot(kind='barh', ax=axes[1], color='k', alpha=0.7) # 橫向柱狀圖
- DataFrame做柱狀圖
df = DataFrame(np.random.rand(6, 4),
index=['one', 'two', 'three', 'four', 'five', 'six'],
columns=pd.Index(['A', 'B', 'C', 'D'], name='Genus'))
print(df)
df.plot(kind='bar')
df數(shù)據(jù)打蛹:
Genus A B C D
one 0.017426 0.964258 0.479931 0.636357
two 0.020693 0.979753 0.846889 0.436802
three 0.650068 0.608675 0.964375 0.866141
four 0.523848 0.610598 0.296204 0.879183
five 0.419329 0.023081 0.442044 0.842727
six 0.926948 0.454734 0.436056 0.970364
- 直方圖和密度圖
comp1 = np.random.normal(0, 1, size=200) # N(0, 1)
comp2 = np.random.normal(10, 2, size=200) # N(10, 4)
values = Series(np.concatenate([comp1, comp2])) # 合并為一個(gè)Series
values.hist(bins=100, alpha=0.3, color = 'k', normed=True) # 直方圖
values.plot(kind='kde', style='k--') # 密度圖(kde表示標(biāo)準(zhǔn)混合正態(tài)分布)
- 散布圖
plt.scatter(trans_data['m1'], trans_data['unemp']) # 散布圖
plt.title('Changes in log %s vs. log %s' % ('m1', 'unemp'))
pd.plotting.scatter_matrix(trans_data, diagonal='kde', color='k', alpha=0.3) # 散布圖矩陣