利用python進行資料分析筆記

來源:互聯網
上載者:User
pandas基礎 流處理

流處理,聽起來很高大上啊,其實就是分塊讀取。有這麼一些情況,有一個很大的幾個G的檔案,沒辦法一次處理,那麼就分批次處理,一次處理1百萬行,接著處理下1百萬行,慢慢地總是能處理完的。

# 使用類似迭代器的方式data=pd.read_csv(file, chunksize=1000000)for sub_df in data:    print('do something in sub_df here')
索引

Series和DataFrame都是有索引的,索引的好處是快速定位,在涉及到兩個Series或DataFrame時可以根據索引自動對齊,比如日期自動對齊,這樣可以省去很多事。 缺失值

pd.isnull(obj)obj.isnull()
將字典轉成資料框,並賦予列名,索引
DataFrame(data, columns=['col1','col2','col3'...],            index = ['i1','i2','i3'...])
查看列名

DataFrame.columns 查看索引

DataFrame.index 重建索引

obj.reindex(['a','b','c','d','e'...], fill_value=0]#按給出的索引順序重新排序,而不是替換索引。如果索引沒有值,就用0填充#就地修改索引data.index=data.index.map(str.upper)
列順序重排(也是重建索引)
DataFrame.reindex[columns=['col1','col2','col3'...])`#也可以同時重建index和columnsDataFrame.reindex[index=['a','b','c'...],columns=['col1','col2','col3'...])
重建索引的快速鍵
DataFrame.ix[['a','b','c'...],['col1','col2','col3'...]]
重新命名軸索引
data.rename(index=str.title,columns=str.upper)#修改某個索引和列名,可以通過傳入字典data.rename(index={'old_index':'new_index'},            columns={'old_col':'new_col'})
查看某一列
DataFrame['state'] 或 DataFrame.state
查看某一行

需要用到索引

DataFrame.ix['index_name']
添加或刪除一列
DataFrame['new_col_name'] = 'char_or_number'#刪除行DataFrame.drop(['index1','index2'...])#刪除列DataFrame.drop(['col1','col2'...],axis=1)#或del DataFrame['col1']
DataFrame選擇子集
類型 說明
obj[val] 選擇一列或多列
obj.ix[val] 選擇一行或多行
obj.ix[:,val] 選擇一列或多列
obj.ix[val1,val2] 同時選擇行和列
reindx 對行和列重新索引
icol,irow 根據整數位置選取單列或單行
get_value,set_value 根據列標籤和欄標籤選擇單個值

針對series

obj[['a','b','c'...]]obj['b':'e']=5

針對dataframe

#選擇多列dataframe[['col1','col2'...]]#選擇多行dataframe[m:n]#條件式篩選dataframe[dataframe['col3'>5]]#選擇子集dataframe.ix[0:3,0:5]
dataframe和series的運算

會根據 index 和 columns 自動對齊然後進行運算,很方便啊

方法 說明
add 加法
sub 減法
div 除法
mul 乘法
#沒有資料的地方用0填充空值df1.add(df2,fill_value=0)# dataframe 與 series 的運算dataframe - series規則是:--------   --------  ||      |   |      |  ||      |   --------  ||      |             ||      |             v--------#指定軸方向dataframe.sub(series,axis=0)規則是:--------   ---  |      |   | |   ----->|      |   | | |      |   | | |      |   | | --------   ---
apply函數
f=lambda x:x.max()-x.min()#預設對每一列應用dataframe.apply(f)#如果需要對每一行分組應用dataframe.apply(f,axis=1)
排序和排名
#預設根據index排序,axis = 1 則根據columns排序dataframe.sort_index(axis=0, ascending=False)# 根據值排序dataframe.sort_index(by=['col1','col2'...])#排名,給出的是rank值series.rank(ascending=False)#如果出現重複值,則取平均秩次#在行或列上面的排名dataframe.rank(axis=0)
描述性統計
方法 說明
count 計數
describe 給出各列的常用統計量
min,max 最大最小值
argmin,argmax 最大最小值的索引位置(整數)
idxmin,idxmax 最大最小值的索引值
quantile 計算樣本分位元
sum,mean 對列求和,均值
mediam 中位元
mad 根據平均值計算平均絕對離差
var,std 方差,標準差
skew 偏度(三階矩)
Kurt 峰度(四階矩)
cumsum 累積和
Cummins,cummax 累計組大致和累計最小值
cumprod 累計積
diff 一階差分
pct_change 計算百分數變化
唯一值,值計數,成員資格
obj.unique()obj.value_count()obj.isin(['b','c'])
處理缺失值
# 過濾缺失值# 只要有缺失值就丟棄這一行dataframe.dropna()#要求全部為缺失才丟棄這一行dataframe.dropna(how='all')# 根據列來判斷dataframe.dropna(how='all',axis=1)# 填充缺失值#1.用0填充df.fillna(0)#2.不同的列用不同的值填充df.fillna({1:0.5, 3:-1})#3.用均值填充df.fillna(df.mean())# 此時axis參數同前面,
將列轉成行索引
df.set_index(['col1','col2'...])
資料清洗,重塑 合并資料集
# 取 df1,df2 都有的部分,丟棄沒有的# 預設是inner的串連方式pd.merge(df1,df2, how='inner')#如果df1,df2的串連欄位名不同,則需要特別指定pd.merge(df1,df2,left_on='l_key',right_on='r_key')#其他的串連方式有 left,right, outer等。# 如果dataframe是多重索引,根據多個鍵進行合并pd.merge(left, right, on=['key1','key2'],how = 'outer')#合并後如果有重複的列名,需要添加尾碼pd.merge(left, right, on='key1', suffixes=('_left','_right'))
索引上的合并
#針對dataframe中的串連鍵不是列名,而是索引名的情況。pd.merge(left, right, left_on = 'col_key', right_index=True)#即左邊的key是列名,右邊的key是index。#多重索引pd.merge(left, right, left_on=['key1','key2'], right_index=True)
dataframe的join方法
#實現按索引合并。#其實這個join方法和資料庫的join函數是以一樣的理解left.join(right, how='outer')#一次合并多個資料框left.join([right1,right2],how='outer')
軸向串連(更常用)

串連:concatenation
綁定:binding
堆疊:stacking 列上的串連

np.concatenation([df1,df2],axis=1)  #np包pd.concat([df1,df2], axis=1) #pd包#和R語言中的 cbind 是一樣的#如果axis=0,則和 rbind 是一樣的#索引對齊,沒有的就為空白# join='inner' 得到交集pd.concat([df1,df2], axis=1, join='innner')# keys 參數,還沒看明白# ignore_index=True,如果只是簡單的合并拼接而不考慮索引問題。pd.concat([df1,df2],ignore_index=True)
合并重複資料

針對可能有索引全部或者部分重疊的兩個資料集

填充因為合并時索引趙成的缺失值

where函數

#where即if-else函數np.where(isnull(a),b,a)

combine_first方法

#如果a中值為空白,就用b中的值填補a[:-2].combine_first(b[2:])#combine_first函數即對資料打補丁,用df2的資料填充df1中的缺失值df1.combine_first(df2)
重塑層次化索引

stact:將資料轉為長格式,即列旋轉為行
unstack:轉為寬格式,即將行旋轉為列

result=data.stack()result.unstack()
長格式轉為寬格式
pivoted = data.pivot('date','item','value')#前兩個參數分別是行和列的索引名,最後一個參數則是用來填充dataframe的資料列的列名。如果忽略最後一個參數,得到的dataframe會帶有層次化的列。
透視表
table = df.pivot_table(values=["Price","Quantity"],            index=["Manager","Rep"],            aggfunc=[np.sum,np.mean],            margins=True))#values:需要對哪些欄位應用函數#index:透視表的行索引(row)#columns:透視表的列索引(column)#aggfunc:應用什麼函數#fill_value:空值填充#margins:添加匯總項#然後可以對透視表進行篩選table.query('Manager == ["Debra Henley"]')table.query('Status == ["pending","won"]')
移除重複資料
# 判斷是否重複data.duplicated()`#移除重複資料data.drop_duplicated()#對指定列判斷是否存在重複值,然後重複資料刪除資料data.drop_duplicated(['key1'])
交叉表

是一種用於計算分組頻率的特殊透視表.
注意,只對離散型的,分類型的,字元型的有用,連續型資料是不能計算頻率這種東西的。

pd.crosstab(df.col1, df.col2, margins=True)
類似vlookup函數

利用函數或映射進行資料轉換

#1.首先定義一個字典meat_to_animal={    'bacon':'pig',    'pulled pork':'pig',    'honey ham':'cow'}#2.對某一列應用一個函數,或者字典,順便根據這一列的結果建立新列data['new_col']=data['food'].map(str.lower).map(meat_to_animal)
替換值
data.replace(-999,np.na)#多個值的替換data.replace([-999,-1000],np.na)#對應替換data.replace([-999,-1000],[np.na,0])#對應替換也可以傳入一個字典data.replace({-999:np.na,-1000:0})
離散化
# 定義分割點# 簡單分割(等寬分箱)s=pd.Series(range(100))pd.cut(s, bins=10, labels=range(10))bins=[20,40,60,80,100]#切割cats = pd.cut(series,bins)#查看標籤cats.labels#查看水平(因子)cats.levels#區間計數pd.value_count(cats)#自訂分區的標籤group_names=['youth','youngAdult','MiddleAge','Senior']pd.cut(ages,bins,labels=group_names)

分位元分割

data=np.random.randn(1000)pd.qcut(data,4)  #四分位元#自訂分位元,包含端點pd.qcut(data,[0,0.3,0.5,0.9,1])
異常值
#查看各個統計量data.describe()#對某一列col=data[3]col[np.abs(col)>3]#選出全部含有“超過3或-3的值的行data[(np.abs(data)>3).any(1)]#異常值替換data[np.abs(data)>3]=np.sign(data)*3
抽樣
#隨機抽取k行df.take(np.random.permutation(len(df))[:k])#隨機抽取k行,但是k可能大於df的行數#可以理解為過抽樣了df.take(np.random.randint(0,len(df),size=k))
資料攤平處理

相當於將類別屬性轉成因子類型,比如是否有車,這個欄位有3個不同的值,有,沒有,過段時間買,那麼將會被編碼成3個欄位,有車,沒車,過段時間買車,每個欄位用0-1二值填充變成數值型。

#對攤平的資料列增加首碼dummies = pd.get_dummies(df['key'],prefix='key')#將攤平產生的資料列拼接回去df[['data1']].join(dummies)
字串操作
# 拆分strings.split(',')#根據Regex切分re.split('\s+',strings)# 串連'a'+'b'+'c'...或者'+'.join(series)# 判斷是否存在's' in strings`strings.find('s')# 計數strings.count(',')# 替換strings.replace('old','new')# 去除空白字元s.strip()
Regex

Regex需要先編譯匹配模式,然後才去匹配尋找,這樣能節省大量的CPU時間。

re.complie:編譯
findall:匹配所有
search:只返回第一個匹配項的起始和結束位址
match:值匹配字串的首部
sub:匹配替換,如果找到就替換

#原始字串strings = 'sdf@153.com,dste@qq.com,sor@gmail.com'#編譯匹配模式,IGNORECASE可以在使用的時候對大小寫不敏感pattern = r'[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}'regex = re.compile(pattern,flags=re.IGNORECASE)#匹配所有regex.findall(strings)#使用searchm = regex.search(strings)  #擷取匹配的地址strings[m.start():m.end()]#匹配替換regex.sub('new_string', strings)
根據模式再切分

將模式切分,也就是將匹配到的進一步切分,通過pattern中的括弧實現.

pattern = r'([A-Z0-9._%+-]+)@([A-Z0-9.-]+)\\.([A-Z]{2,4})'regex = re.compile(pattern)regex.findall(strings)#如果使用matchm=regex.match(string)m.groups()#效果是這樣的suzyu123@163.com --> [(suzyu123, 163, com)]#擷取 list-tuple 其中的某一列matches.get(i)
分組彙總,計算 group_by技術
# 根據多個索引分組,然後計算均值means = df['data1'].groupby([df['index1'],df['index2']).mean()# 展開成透視表格式means.unstack()
分組後價將片段做成一個字典
pieces = dict(list(df.groupby('index1')))pieces['b']

groupby預設是對列(axis=0)分組,也可以在行(axis=1)上分組 文法糖,groupby的快捷函數

df.groupby('index1')['col_names']df.groupby('index1')[['col_names']]#是下面代碼的文法糖df['col_names'].groupby(df['index1'])df.groupby(['index1','index2'])['col_names'].mean()
通過字典或series進行分組
people = DataFrame(np.random.randn(5, 5),                    columns=['a', 'b', 'c', 'd', 'e'],                    index=['Joe', 'Steve', 'Wes', 'Jim','Travis'])# 選擇部分設為napeople.ix[2:3,['b','c']]=np.namapping = {'a': 'red', 'b': 'red', 'c': 'blue',            'd': 'blue', 'e': 'red', 'f' : 'orange'}people.groupby(mapping,axis=1).sum()
通過函數進行分組
#根據索引的長度進行分組people.groupby(len).sum()
資料彙總 使用自訂函數
## 對所有的資料列使用自訂函數df.groupby('index1').agg(myfunc)#使用系統函數df.groupby('index1')['data1']describe()
根據列分組應用多個函數
#分組grouped = df.groupby(['col1','col2'])#選擇多列,對每一列應用多個函數grouped['data1','data2'...].agg(['mean','std','myfunc'])
對不同列使用不同的函數
grouped = df.groupby(['col1','col2'])#傳入一個字典,對不同的列使用不同的函數#不同的列可以應用不同數量的函數grouped.agg({'data1':['min','max','mean','std'],                'data2':'sum'})
分組計算後重新命名列名
grouped = df.groupby(['col1','col2'])grouped.agg({'data1':[('min','max','mean','std'),('d_min','d_max','d_mean','d_std')],                'data2':'sum'})
返回的彙總資料不要索引
df.groupby(['sex','smoker'], as_index=False).mean()
分組計算結果添加首碼
#對計算後的列名添加首碼df.groupby('index1').mean().add_prefix('mean_')
將分組計算後的值替換到原資料框
#將函數應用到各分組,再將分組計算的結果代換原資料框的值#也可以使用自訂函數df.groupby(['index1','index2'...]).transform(np.mean)
更一般化的apply函數
df.groupby(['col1','col2'...]).apply(myfunc)df.groupby(['col1','col2'...]).apply(['min','max','mean','std'])
禁用分組鍵

分組鍵會跟原始對象的索引共同構成結果對象中的層次化索引

df.groupby('smoker', group_keys=False).apply(mean)
分組索引轉成df的列

某些情況下,groupby的as_index=False參數並沒有什麼用,得到的還是一個series,這種情況一般是儘管分組了,但是計算需要涉及幾列,最後得到的還是series,series的index是層次化索引。這裡將series轉成dataframe,series的層次化索引轉成dataframe的列。

def fmean(df):    """需要用兩列才能計算最後的結果"""    skus=len(df['sku'].unique())    sums=df['salecount'].sum()    return sums/skus#儘管禁用分組鍵,得到的還是seriessalemean=data.groupby(by=['season','syear','smonth'],as_index=False).apply(fmean)# 將series轉成dataframe,順便設定索引sub_df = pd.DataFrame(salemean.index.tolist(),columns=salemean.index.names,index=salemean.index)# 將groupby的結果和sub_df合并sub_df['salemean']=salemean
桶分析與分位元

對資料切分段,然後對每一分段應用函數

frame = DataFrame({'col1':np.random.randn(1000),                    'col2':np.random.randn(1000)})#資料分段,建立分段用的因子#返回每一元素是屬於哪一分割區間factor = pd.cut(frame.col1, 4)#分組計算,然後轉成資料框形式grouped = frame.col2.groupby(factor)grouped.apply(myfunc).unstack()
用分組的均值填充缺失值
#自訂函數fill_mean= lambda x:x.fillna(x.mean())#分組填充df.groupby(group_key).apply(fill_mean)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.