Python數(shù)據(jù)分析 :pandas數(shù)據(jù)讀取、預(yù)處理、篩選、計(jì)算,時(shí)間序列、透視、拼接、導(dǎo)出

一、Pandas數(shù)據(jù)結(jié)構(gòu)

S1=pd.Series([‘a(chǎn)’,’b’,’c’]) series是一組數(shù)據(jù)與一組索引(行索引)組成的數(shù)據(jù)結(jié)構(gòu)
S1=pd.Series([‘a(chǎn)’,’b’,’c’],index=(1,3,4)) 指定索引
S1=pd.Series({1:‘a(chǎn)’,2:’b’,3:’c’}) 用字典形式指定索引
S1.index() 返回索引
S1.values() 返回值
Df=pd.DataFrame([‘a(chǎn)’,’b’,’c’]) dataframe是一組數(shù)據(jù)與兩組索引(行列索引)組成的數(shù)據(jù)結(jié)構(gòu)
Df=pd.DataFrame([[a,A],[b,B],[c,C]],columns=[‘小寫(xiě)’,’大寫(xiě)’],index=[‘一’,’二’,’三’])
Columms 為列索引,index為行索引
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pyspider 清華鏡像

  • 查找某個(gè)包 anaconda search -t conda tensorflow
    下載某個(gè)包 anaconda show package
    data={‘小寫(xiě)’:[‘a(chǎn)’,’b’,’c’],’大寫(xiě)’:[‘A’,’B’,’C’]} 傳入字典
    Df=Pd.DataFrame(data)
    Df.index() df.columns()
  • 建立分層索引的dataframe:pd.MultiIndex.from_arrays([[,,]],name=[,,])

二、讀取數(shù)據(jù)

df=pd.read_excel(r’C:\user...xlsx’,sheet_name=’sheet1’) 或
pd.read_excel(r’C:\user...xlsx’,sheet_name=0) 讀取excel表
pd.read_excel(r’C:\user...xlsx’,index_col=0,header=0)
index_col指定行索引,header指定列索引
pd.read_excel(r’C:\user...xlsx’,usecols=[0,1]) 導(dǎo)入指定列,不能有index_col和header
pd.read_tablel(r’C:\user...txt’,sep=’ ’) 導(dǎo)入txt文件,sep指定分隔符是什么
df.head(2) 展示前兩行,默認(rèn)展示前5行
df.shape 顯示數(shù)據(jù)幾行幾列,不包含行和列索引
df.info()可查看表中數(shù)據(jù)的類(lèi)型
df.describe() 可獲得表中數(shù)值類(lèi)型指端的分布值(和、平均值、方差等)

三、數(shù)據(jù)預(yù)處理

  • 多個(gè)Series合并成DataFrame:pd.DataFrame(list(zip(series_1, series_2)))
  • python在字符串前面加0:str(1).zfill(2)
    df.info() 可顯示表中哪個(gè)數(shù)據(jù)為空
    df.isnull() 方法可以判斷哪個(gè)值是缺失值,如果缺失返回True,否則為False
    df.dropna() 默認(rèn)刪除含缺失值的行
    df.dropna(how=’all’) 刪除全為空值的行,不全為空值的行不會(huì)刪除
    df.fillna(0) 用0填充所有空值
    df.fillna({‘性別’:’男’,’年齡’:’30’}) 對(duì)性別列中空值填充男,年齡填充30
  • 通過(guò)隨機(jī)選擇非缺失值來(lái)填充缺失值
    foo['A'].apply(lambda x: np.random.choice(
    [x for x in range(min(foo['A']),max(foo['A'])]) if (np.isnan(x)) else x)
  • 按一列數(shù)據(jù)填充另一列數(shù)據(jù)中的缺失值
    df_real['凈含量'] = df_real['凈含量'].fillna(df_real['凈含量_y'])
  • df1.combine_first(df2):將df2的非缺失值填充df1中的缺失(dataframe根據(jù)列名和索引)值;
    ser1.combine_first(ser2):用ser2的非缺失值填充ser1中的缺失值(series根據(jù)索引)
  • 按指定的字符合并多列:df['A'].str.cat([df['B'], df['C']], sep='-')
    df.drop_duplicates(inplace=True) 默認(rèn)對(duì)所有值進(jìn)行重復(fù)值檢查,保留第一行的值,inplace=True表示直接在原來(lái)的DataFrame上刪除重復(fù)項(xiàng),而默認(rèn)值False表示生成一個(gè)副本。
    df.drop_duplicates(subset=’性別’) 對(duì)性別列中重復(fù)值查詢保留第一行
    df.drop_duplicates(subset=[’性別’,’公司’],keep=’last’) 對(duì)性別和公司兩列查重
    keep設(shè)置默認(rèn)為first(保留第一個(gè)),可設(shè)置為last(保留最后一個(gè)) 或False(都不保留)
    df[‘ID’].dtype 查看ID列的數(shù)據(jù)類(lèi)型
    df[‘ID’].astype(‘float’) 將ID列的數(shù)據(jù)類(lèi)型轉(zhuǎn)換為float類(lèi)型
    數(shù)據(jù)類(lèi)型:int、float、object、string、unicode、datetime
    df[‘ID’][1] ID列的第二個(gè)數(shù)據(jù)
    df.columns=[‘大寫(xiě)’,’小寫(xiě)’,’中文’] 為無(wú)索引表添加列索引
    df.index=[1,2,3] 添加行索引
    df.set_index(‘編號(hào)’) 指明要用的列作為行索列
    df.rename(index={‘訂單編號(hào)’:’新訂單編號(hào)’,’客戶姓名’:’新客戶姓名’}) 對(duì)行索引進(jìn)行重新命名
    df.rename(columns={1:’一’,2:’二’}) 對(duì)列索引進(jìn)行一次性重新命名所有列名
    如果你需要做的僅僅是將空格換成下劃線,那么更好的辦法是使用str.replace()方法,這是因?yàn)槟愣疾恍枰斎胨械牧忻?br> df.columns = df.columns.str.replace( , _ )
    df.reset_index() 默認(rèn)將全部index轉(zhuǎn)化為column,
    df.reset_index(level=0) 將0級(jí)索引轉(zhuǎn)化為column
    df.reset_index(drop=True) 刪除原有索引
  • 多列合并為一行
    df = pd.DataFrame({'id_part':['a','b','c','d'], 'pred':[0.1,0.2,0.3,0.4], 'pred_class':['women','man','cat','dog'], 'v_id':['d1','d2','d3','d1']})
    df.groupby(['v_id']).agg({'pred_class': [', '.join],'pred': lambda x: list(x),'id_part': 'first'}).reset_index()
  • 字符串轉(zhuǎn)換為數(shù)值
    df = pd.DataFrame({'列1':['1.1','2.2','3.3'],
    '列2':['4.4','5.5','6.6'],
    '列3':['7.7','8.8','-']})
    df.astype({'列1':'float','列2':'float'}).dtypes
    用這種方式轉(zhuǎn)換第三列會(huì)出錯(cuò),因?yàn)檫@列里包含一個(gè)代表 0 的下劃線,pandas 無(wú)法自動(dòng)判斷這個(gè)下劃線。為了解決這個(gè)問(wèn)題,可以使用 to_numeric() 函數(shù)來(lái)處理第三列,讓 pandas 把任意無(wú)效輸入轉(zhuǎn)為 NaN。
    df = df.apply(pd.to_numeric, errors='coerce').fillna(0)
  • 優(yōu)化 DataFrame 對(duì)內(nèi)存的占用
    方法一:只讀取切實(shí)所需的列,使用usecols參數(shù)
    cols = ['beer_servings','continent']
    small_drinks = pd.read_csv('data/drinks.csv', usecols=cols)
    方法二:把包含類(lèi)別型數(shù)據(jù)的 object 列轉(zhuǎn)換為 Category 數(shù)據(jù)類(lèi)型,通過(guò)指定 dtype 參數(shù)實(shí)現(xiàn)。
    dtypes ={'continent':'category'}
    smaller_drinks = pd.read_csv('data/drinks.csv',usecols=cols, dtype=dtypes)
  • 把字符串分割為多列
    df = pd.DataFrame({'姓名':['張 三','李 四','王 五'],
    '所在地':['北京-東城區(qū)','上海-黃浦區(qū)','廣州-白云區(qū)']})
    df.姓名.str.split(' ', expand=True)
  • 把 Series 里的列表轉(zhuǎn)換為 DataFrame
    df = pd.DataFrame({'列1':['a','b','c'],'列2':[[10,20], [20,30], [30,40]]})
    df_new = df.列2.apply(pd.Series)
    pd.concat([df,df_new], axis='columns')
  • DataFrame迭代:
    iterrows():將DataFrame迭代為(insex, Series)對(duì)。
    iteritems():將DataFrame迭代為(列名, Series)對(duì)。
    itertuples(): 將DataFrame迭代為元組。
    for row in df.itertuples():
    print(row)
    print('----------------')
    print(getattr(row,'col1'), getattr(row,'col2'))
    getattr() 函數(shù)用于返回一個(gè)對(duì)象屬性值。

四、數(shù)據(jù)選擇

  • Query是pandas的過(guò)濾查詢函數(shù),使用布爾表達(dá)式來(lái)查詢DataFrame的列,就是說(shuō)按照列的規(guī)則進(jìn)行過(guò)濾操作。
    pandas.DataFrame.query(self, expr, inplace = False, **kwargs)
    expr:要評(píng)估的查詢字符串;
    inplace=False:查詢是應(yīng)該修改數(shù)據(jù)還是返回修改后的副本
    kwargs:dict關(guān)鍵字參數(shù)
    比如要查列value_1<value_2的行記錄:df.query('value_1 < value_2')
    查詢列year>=2016的行記錄:df.query('year >= 2016 ')
  • Insert用于在DataFrame的指定位置中插入新的數(shù)據(jù)列。默認(rèn)情況下新列是添加到末尾的,但可以更改位置參數(shù),將新列添加到任何位置。
    Dataframe.insert(loc, column, value, allow_duplicates=False)
    loc: int型,表示插入位置在第幾列;若在第一列插入數(shù)據(jù),則 loc=0
    column: 給插入的列取名,如 column='新的一列'
    value:新列的值,數(shù)字、array、series等都可以
    allow_duplicates: 是否允許列名重復(fù),選擇Ture表示允許新的列名與已存在的列名重復(fù)
    在第三列的位置插入新列:df.insert(2, 'new_col', new_col)
  • Cumsum是pandas的累加函數(shù),用來(lái)求列的累加值。 用法:
    DataFrame.cumsum(axis=None, skipna=True, args, kwargs)
    axis:index或者軸的名字
    skipna:排除NA/null值
    df中的group列有A、B、C三組,year列有多個(gè)年份。我們只知道當(dāng)年度的值value_1、value_2,現(xiàn)在求group分組下的累計(jì)值,比如A、2014之前的累計(jì)值,可以用cumsum函數(shù)來(lái)實(shí)現(xiàn)。
    當(dāng)然僅用cumsum函數(shù)沒(méi)辦法對(duì)groups (A, B, C)進(jìn)行區(qū)分,所以需要結(jié)合分組函數(shù)groupby分別對(duì)(A, B, C)進(jìn)行值的累加。
    df['cumsum_2'] = df[['value_2','group']].groupby('group').cumsum()
  • Sample用于從DataFrame中隨機(jī)選取若干個(gè)行或列。 用法:
    DataFrame.sample(n=None, frac=None, replace=False, weights=None, random_state=None, axis=None)
    n:要抽取的行數(shù)
    frac:抽取行的比例 例如frac=0.8,就是抽取其中80%
    replace:是否為有放回抽樣, True:有放回抽樣 False:未放回抽樣
    weights:字符索引或概率數(shù)組
    random_state :隨機(jī)數(shù)發(fā)生器種子
    axis:選擇抽取數(shù)據(jù)的行還是列 axis=0:抽取行 axis=1:抽取列
    從df中隨機(jī)抽取5行:df.sample(n=5)
    從df隨機(jī)抽取60%的行,并且設(shè)置隨機(jī)數(shù)種子,每次能抽取到一樣的樣本:df.sample(frac=0.6,random_state=2)
  • Where用來(lái)根據(jù)條件替換行或列中的值。如果滿足條件,保持原來(lái)的值,不滿足條件則替換為其他值。默認(rèn)替換為NaN,也可以指定特殊值。
    DataFrame.where(cond, other=nan, inplace=False, axis=None, level=None, errors='raise', try_cast=False, raise_on_error=None)
    cond:布爾條件,如果 cond 為真,保持原來(lái)的值,否則替換為other
    other:替換的特殊值
    inplace:inplace為真則在原數(shù)據(jù)上操作,為False則在原數(shù)據(jù)的copy上操作
    axis:行或列
    將df中列value_1里小于5的值替換為0:df['value_1'].where(df['value_1'] > 5 , 0)
  • 得到DataFrame中重復(fù)的數(shù)據(jù)
    data={'one':[1,1,2,2,1,2,2],'two':['a','b','c','d','b','c','d']}
    frame=pd.DataFrame(data)
    print("***************原始數(shù)據(jù)*************")
    print(frame)
    data1 = frame.drop_duplicates(subset=['two'],keep='first')
    print("***************去重后的數(shù)據(jù)*************")
    print(data1)
    a = frame.drop_duplicates(subset=['two'],keep='last')
    b = frame.drop_duplicates(subset=['two'],keep=False)
    c=a.append(b).drop_duplicates(subset=['two'],keep=False)
    print("***************重復(fù)的數(shù)據(jù)*************")
    print(c)

df[[‘ID’,’姓名’]] 多個(gè)列名要裝入list
df.iloc[[1,3],[2,4]] 用行列編號(hào)選擇數(shù)據(jù)
df.iloc[1,1] 選取表中的第3行2列數(shù)據(jù),第一行默認(rèn)為列索引
df.iloc[:,0:4] #獲取第1列到第4列的值
df.loc[‘一’] #loc用行名選取的行數(shù)據(jù),格式是Series,但可以用列表形式訪問(wèn)
df.loc[‘一’][0] 或 df.loc[‘一’][‘序號(hào)’]
df.iloc[1]#iloc用行編號(hào)選取行數(shù)據(jù)
df.iloc[[1,3]]#多行編號(hào)選取行數(shù)據(jù),要用list封裝,不然變成行列選取
df.iloc[1:3]#選擇第二行和第四行
df[df[‘年齡’]<45] #加判斷條件返回符合條件的全部數(shù)據(jù),不局限年齡列
df[(df[‘年齡’]<45)&(df[‘ID’]<4)] #判斷多條件選擇數(shù)據(jù)
df.iloc[[1,3],[2,4]] 相當(dāng)于df.loc[[‘一’,’二’],[‘年齡’,’ID’]] #loc是名,iloc是編號(hào)
df[df[‘年齡’]<45][[‘年齡’,’ID’]]#先通過(guò)年齡條件選擇行,再通過(guò)不同索引指定列
df.iloc[1:3,2:4]#切片索引

  • 行序、列序反轉(zhuǎn) :行序反轉(zhuǎn)最直接的辦法是使用loc函數(shù)并傳遞::-1,跟Python中列表反轉(zhuǎn)時(shí)使用的切片符號(hào)一致
    df.loc[::-1].reset_index(drop=True)
    列序反轉(zhuǎn)就比較容易了,只需要如下操作:df.loc[:, ::-1]
  • 分組里最大值所在的行方法
    分為分組中有重復(fù)值和無(wú)重復(fù)值兩種。無(wú)重復(fù)值的情況。
    df = pd.DataFrame({'Sp':['a','b','c','d','e','f'], 'Mt':['s1', 's1', 's2','s2','s2','s3'], 'Value':[1,2,3,4,5,6], 'Count':[3,2,5,10,10,6]})
    df.iloc[df.groupby(['Mt']).apply(lambda x: x['Count'].idxmax())]
    先按Mt列進(jìn)行分組,然后對(duì)分組之后的數(shù)據(jù)框使用idxmax函數(shù)取出Count最大值所在的列,再用iloc位置索引將行取出。有重復(fù)值的情況
    df["rank"] = df.groupby("ID")["score"].rank(method="min", ascending=False).astype(np.int64)
    df[df["rank"] == 1][["ID", "class"]]
    對(duì)ID進(jìn)行分組之后再對(duì)分?jǐn)?shù)應(yīng)用rank函數(shù),分?jǐn)?shù)相同的情況會(huì)賦予相同的排名,然后取出排名為1的數(shù)據(jù)。
  • 選擇特定類(lèi)型的列
    drinks = pd.read_csv('data/drinks.csv')
    選擇所有數(shù)值型的列
    drinks.select_dtypes(include=['number']).head()
    選擇所有字符型的列
    drinks.select_dtypes(include=['object']).head()
    drinks.select_dtypes(include=['number','object','category','datetime']).head()
    用 exclude 關(guān)鍵字排除指定的數(shù)據(jù)類(lèi)型
    drinks.select_dtypes(exclude=['number']).head()
  • 根據(jù)最大的類(lèi)別篩選 DataFrame
    movies = pd.read_csv('data/imdb_1000.csv')
    counts = movies.genre.value_counts()
    movies[movies.genre.isin(counts.nlargest(3).index)].head()
  • 基于字符串的長(zhǎng)度來(lái)篩選數(shù)據(jù)
    df[df.col1.str.len() > 20].head()
  • 標(biāo)注重點(diǎn)
    df_new.style.highlight_max(axis = 0, color = "yellow")

五、數(shù)值操作

df[‘年齡’].replace(100,33)#對(duì)年齡列中的100替換成33
df.replace(np.NaN,0)#相當(dāng)于fillna(),其中np.NaN是python中缺省值的表示方式
df.replace([A,B],C)#多對(duì)一替換,A、B替換成C
df.replace({‘A’:’a’,‘B’:’b’,‘C’:’c’})#多對(duì)多替換
df.sort_values(by=['申請(qǐng)單編號(hào)'],ascending=False)#申請(qǐng)單編號(hào)列降序排列,Ture升序排列(默認(rèn))
df.sort_values(by=['申請(qǐng)單編號(hào)'],na_position=’first’)#申請(qǐng)單編號(hào)列升序排列,缺失值排在第一位
默認(rèn)缺失值在最后一位last
df = pd.DataFrame([['A',1],['A',3],['A',2],['B',5],['B',9]], columns = ['name','score'])
df.sort_values(['name','score'], ascending = [True,False])#多列排序
df.groupby('name').apply(lambda x: x.sort_values('score',ascending=False)).reset_index(drop=True)

  • Pct_change是一個(gè)統(tǒng)計(jì)函數(shù),用于表示當(dāng)前元素與前面元素的相差百分比,兩元素的區(qū)間可以調(diào)整。
    比如說(shuō)給定三個(gè)元素[2,3,6],計(jì)算相差百分比后得到[NaN, 0.5, 1.0],從第一個(gè)元素到第二個(gè)元素增加50%,從第二個(gè)元素到第三個(gè)元素增加100%。
    DataFrame.pct_change(periods=1, fill_method=‘pad’, limit=None, freq=None, **kwargs)
    periods:間隔區(qū)間,即步長(zhǎng)
    fill_method:處理空值的方法
    對(duì)df的value_1列進(jìn)行增長(zhǎng)率的計(jì)算:df.value_1.pct_change()

df[‘銷(xiāo)量’].rank(method=’first’)#銷(xiāo)量排名(不是排序),method有first\min\max\average

  • pandas 進(jìn)行組內(nèi)排序、單組排序、標(biāo)號(hào)
    組內(nèi)進(jìn)行排序(按user_id分組后對(duì)product_id排序)
    data1['group_sort']=data1['product_id'].groupby(data1['user_id']).rank(ascending=1,method='first')

df.drop([‘銷(xiāo)量’,’ID’],axis=1)#刪除列,直接是列名,inpace=True是保留修改哦
df.drop(df.columns[[4,5]],axis=1)#刪除列,是編號(hào)
df.drop(colums=[‘銷(xiāo)量’,’ID’])#此種方式刪除列,可以不寫(xiě)axis=1
df.drop([‘a(chǎn)’,’b’],axis=0)#刪除行,直接是列名
df.drop(df.index[[4,5]],axis=0)#刪除行,是編號(hào)
df.drop(index=[‘a(chǎn)’,’b’])#此種方式刪除行,可以不寫(xiě)axis=0
df[‘ID’].value_counts()#對(duì)ID列中數(shù)據(jù)出現(xiàn)的次數(shù)進(jìn)行統(tǒng)計(jì)
df[‘ID’].value_counts(normalize=Ture,sort=False)#對(duì)ID列中數(shù)據(jù)出現(xiàn)的次數(shù)占比進(jìn)行統(tǒng)計(jì),并降序排序
df[‘ID’].unique()#獲取列的唯一值
df[‘年齡’].isin([‘a(chǎn)’,11])#查看這列中是否包含a或11
pd.cut(df[‘ID’],bins=[0,3,6,10])#用bins指明切分區(qū)間
pd.qcut(df[‘ID’],3)#ID列切分成3個(gè)部分,每部分?jǐn)?shù)據(jù)個(gè)數(shù)盡量一致
df.insert(2,’商品’,[‘書(shū)’,’筆’,’計(jì)算器’])#插入第三列
df[’商品’]=[‘書(shū)’,’筆’,’計(jì)算器’])#插新列,在表的最后面
df.T行列互換
df.tack()#把表格型數(shù)據(jù)轉(zhuǎn)化成樹(shù)形數(shù)據(jù)
df.set_index([‘ID’,’姓名’]).stack().reset_index()#寬表轉(zhuǎn)換成長(zhǎng)表,先將共同列設(shè)置成行索引,再對(duì)其他列
進(jìn)行轉(zhuǎn)化成樹(shù)形數(shù)據(jù),再重置行索引

  • 堆疊:pd.DataFrame.stack(self, level=-1, dropna=True),level默認(rèn)為-1是將最內(nèi)層col堆疊為索引的最內(nèi)層,為0是將最外層col堆疊為索引的最內(nèi)層,從最外層開(kāi)始依次的level值為0,1,2...的順序來(lái)指定對(duì)應(yīng)col。當(dāng)然直接指定索引名稱或許是更好的選擇。

  • 反堆疊、拆堆:pd.DataFrame.unstack(self, level=-1, fill_value=None),默認(rèn)將最內(nèi)層的索引拆堆到列的最內(nèi)層,其他同理stack();

  • df.melt(id_vars=[‘ID’,’姓名’],var_name=’year’,value_name=’sale’)
    id_var參數(shù)指明寬表轉(zhuǎn)換成長(zhǎng)表時(shí)保持不變的列,var_name參數(shù)表示原來(lái)的列索引轉(zhuǎn)化為行索引對(duì)應(yīng)的列名,value_name表示新索引對(duì)應(yīng)值的列名
    df[‘C1’].apply(lambda x:x+1)#相當(dāng)于map(),只是需要和lambda配合
    df.applymap(lambda x:x+1),對(duì)表中的所有數(shù)據(jù)執(zhí)行相同函數(shù)運(yùn)算

  • apply搭配匿名函數(shù)lambda的神奇用法:
    df['數(shù)據(jù)3'] = df.apply(lambda x:(x.數(shù)據(jù)1-x.數(shù)據(jù)2)/x.上月 if x.col3!=0 else 0 ,axis=1)

  • 刪除包含特定字符串所在的
    行:df['b'].values.astype('str') 先轉(zhuǎn)為字符串格式最好;
    df[df['b'].str.contains('exp',na=False)]

  • 計(jì)算變量缺失率
    def missing_cal(df):
    """
    df :數(shù)據(jù)集
    return:每個(gè)變量的缺失率
    """
    missing_series = df.isnull().sum()/df.shape[0]
    missing_df = pd.DataFrame(missing_series).reset_index()
    missing_df = missing_df.rename(columns={'index':'col',
    0:'missing_pct'})
    missing_df = missing_df.sort_values('missing_pct',ascending=False).reset_index(drop=True)
    return missing_df
    missing_cal(df)
    如果需要計(jì)算樣本的缺失率分布,只要加上參數(shù)axis=1。

六、數(shù)據(jù)運(yùn)算

df[‘ID’]+Df[‘ID’]#可進(jìn)行加減乘除
df[‘ID’]>Df[‘ID’]#可進(jìn)行> < == !=等比較運(yùn)算
df.nunique()#統(tǒng)計(jì)每列不重復(fù)值的個(gè)數(shù)
df.count()#統(tǒng)計(jì)每列的非空值的個(gè)數(shù)
df.count(axis=1)#統(tǒng)計(jì)每行的非空值的個(gè)數(shù)
df[‘ID’].count()#統(tǒng)計(jì)指定列的非空值的個(gè)數(shù)
df.sum(axis=1)#每列/行求和結(jié)果
df.mean(axis=1)#每列/行求均值
df.max(axis=1)#每列/行求最大值
df.min(axis=1)#每列/行求最小值
df.median(axis=1)#每列/行求中間值
df.mode(axis=1)#每列/行中出現(xiàn)最多的值
df.var(axis=1)#每列/行求方差
df.std(axis=1)#每列/行求標(biāo)準(zhǔn)差
df.quantile(0.25)#求1/4分位數(shù),可以0.5、0.75等分位數(shù)
df.corr()#求整個(gè)DataFrame表中的相關(guān)性

七、時(shí)間序列

from datetime import datetime
datatime.now()#返回現(xiàn)在的時(shí)間年月日時(shí)分秒
datatime.now().year#返回年,可以.month.day
datatime.now().weekday()-1#返回周幾
datatime.now().isocalendar()#返回周數(shù)
(2018,41,7)#2018年的第41周第7天
datatime.now().date()#只返回年月日
datatime.now().time()#只返回時(shí)間
datatime.now().strftime(‘%Y-%m-%d %H:%M:%S’)#返回2020-03-13 09:09:12
pd.to_datetime(['201221'],format = "%Y%m%d")#返回DatetimeIndex(['2012-02-01'], dtype='datetime64[ns]', freq=None)
pd.to_datetime('201221',format = "%Y%m%d")#不加列表,返回Timestamp('2012-02-01 00:00:00'),需要省去時(shí)分秒可以在后面加.strftime("%Y-%m-%d")
from dateutil.parser import parse
parse(str_time)#將字符串的時(shí)間轉(zhuǎn)化成為時(shí)間格式
pd.Datetimeindex([‘2020-02-03’,2020-03-05’])#設(shè)置時(shí)間索引
data[‘2018’]#獲取2018年的數(shù)據(jù)
data[‘2018-01’]#獲取2018年1月的數(shù)據(jù)
data[‘2018-01-05’:‘2018-01-15’]#獲取這個(gè)時(shí)段的數(shù)據(jù)
非時(shí)間索引的表格處理
df[df[‘成交時(shí)間’]==datetime(2018,08,05)]
df[df[‘成交時(shí)間’]>datetime(2018,08,05)]
df[(df[‘成交時(shí)間’]>datetime(2018,08,05))&(df[‘成交時(shí)間’] <datetime(2018,08,15))]
cha=datatime(2018,5,21,19,50)-datatime(2018,5,18,17,50)
cha.days#返回天的時(shí)間差
cha.seconds#返回秒的時(shí)間差
cha.seconds/3600#返回小時(shí)的時(shí)間差
datatime(2018,5,21,19,50)+timedelta(days=1)#往后移一天
datatime(2018,5,21,19,50)+timedelta(seconds=20)#往后移20秒
datatime(2018,5,21,19,50)-timedelta(days=1)#往前移一天

日期時(shí)間類(lèi)型接口一覽表

df = generate_sample_data_datetime().reset_index()
df = df.sample(500)
df["Year"] = df["index"].dt.year
df["Month"] = df["index"].dt.month
df["Day"] = df["index"].dt.day
df["Hour"] = df["index"].dt.hour
df["Minute"] = df["index"].dt.minute
df["Second"] = df["index"].dt.second
df["Nanosecond"] = df["index"].dt.nanosecond
df["Date"] = df["index"].dt.date
df["Time"] = df["index"].dt.time
df["Time_Time_Zone"] = df["index"].dt.timetz
df["Day_Of_Year"] = df["index"].dt.dayofyear
df["Week_Of_Year"] = df["index"].dt.weekofyear
df["Week"] = df["index"].dt.week
df["Day_Of_week"] = df["index"].dt.dayofweek
df["Week_Day"] = df["index"].dt.weekday
df["Week_Day_Name"] = df["index"].dt.weekday_name
df["Quarter"] = df["index"].dt.quarter
df["Days_In_Month"] = df["index"].dt.days_in_month
df["Is_Month_Start"] = df["index"].dt.is_month_start
df["Is_Month_End"] = df["index"].dt.is_month_end
df["Is_Quarter_Start"] = df["index"].dt.is_quarter_start
df["Is_Quarter_End"] = df["index"].dt.is_quarter_end
df["Is_Leap_Year"] = df["index"].dt.is_leap_year

八、數(shù)據(jù)透視表

df.groupby(‘客戶分類(lèi)’).count()#客戶分類(lèi)后求數(shù)運(yùn)算
df.groupby(‘客戶分類(lèi)’).sum()#客戶分類(lèi)后求和運(yùn)算
df.groupby(‘客戶分類(lèi)’,’區(qū)域分類(lèi)’).sum()#多列分類(lèi)后求和運(yùn)算
df.groupby(‘客戶分類(lèi)’,’區(qū)域分類(lèi)’)[‘ID’].sum()#多列分類(lèi)后ID求和運(yùn)算
df[‘ID’]#DataFrame取出一列就是Series類(lèi)型
df.groupby(df[‘ID’]).sum() 相當(dāng)于 df.groupby(‘ID’).sum()
df.groupby(‘客戶分類(lèi)’).aggregate([‘sum’,’count’]# aggregate可實(shí)現(xiàn)多種匯總方式
df.groupby(‘客戶分類(lèi)’).aggregate({‘ID’:‘count’,’銷(xiāo)量’: ‘sum’})

  • 用多個(gè)函數(shù)聚合
    df.groupby('order_id').item_price.agg(['sum','count']).head()
  • aggregate可針對(duì)不同列做不同的匯總運(yùn)算
    df.groupby(‘客戶分類(lèi)’).sum().reset_index()#分組匯總后再重置索引,變?yōu)闃?biāo)準(zhǔn)DataFrame
    pd.pivot_table(data,values,index,columms,aggfunc,fill_value,margins,dropna,margins_name)
    數(shù)據(jù)透視表,data:數(shù)據(jù)表df,values:值,index:行索引,columns:列索引,aggfunc:values的計(jì)算類(lèi)型,fill_value:對(duì)空值的填充方式;margins:是否有合計(jì)列;margins_name:合計(jì)列的列名
    pd.pivot_table(df,values=[’ID’,‘銷(xiāo)量’],index=’客戶分類(lèi)’,columms=‘區(qū)域’,aggfunc={‘ID’:‘count’,’銷(xiāo)量’:‘sum’}),fill_value=0,margins=Ture,dropna=None,margins_name=’總計(jì)’)
  • 分組聚合 dict(list(df.groupby('key1')))
    通過(guò)字典或Series進(jìn)行分組
    people = pd.DataFrame(np.random.randn(5, 5),columns=['a', 'b', 'c', 'd', 'e'],index=['Joe', 'Steve', 'Wes', 'Jim', 'Travis'])
    mapping = {'a':'red', 'b':'red', 'c':'blue', 'd':'blue', 'e':'red', 'f':'orange'}
    by_column = people.groupby(mapping, axis=1)
    by_column.sum()

九、多表格拼接

pd.merge(df1,df2)#默認(rèn)自動(dòng)尋找兩個(gè)表中的公共列進(jìn)行拼接
pd.merge(df1,df2,on=“學(xué)號(hào)“)#on來(lái)指定連接列,連接列要是公共列
pd.merge(df1,df2,on=[‘學(xué)號(hào)’,’姓名’]#on來(lái)指定連接列,連接列要是公共列
pd.merge(df1,df2,left_on=‘學(xué)號(hào)’right_on=’編號(hào)’) #由公共列,但類(lèi)名不同時(shí)用左右鍵指定
pd.merge(df1,df2,left_index=‘學(xué)號(hào)’right_index=’編號(hào)’)#兩表公共列都是索引列時(shí)
pd.merge(df1,df2,left_index=‘學(xué)號(hào)’right_on=’編號(hào)’)#公共列一個(gè)時(shí)索引列一個(gè)時(shí)普通列
pd.merge(df1,df2,on=’學(xué)號(hào)’,how=’inner’)#返回公共列中對(duì)應(yīng)的公共值拼接(內(nèi)連接)
pd.merge(df1,df2,on=’學(xué)號(hào)’,how=’left’)#返回公共列中對(duì)應(yīng)的左表值(左連接)
pd.merge(df1,df2,on=’學(xué)號(hào)’,how=’right’)#返回公共列中對(duì)應(yīng)的右表值(右連接)
pd.merge(df1,df2,on=’學(xué)號(hào)’,how=’outer’)#返回公共列中對(duì)應(yīng)的所有值(外連接)
pd.concat([df1,df2])#兩個(gè)結(jié)構(gòu)相同的表縱向連接,保留原索引值
pd.concat([df1,df2],ignore_index=True)#兩個(gè)結(jié)構(gòu)相同的表縱向連接,重新設(shè)置索引值
pd.concat([df1,df2],ignore_index=True).drop_duplicates()#拼接后去掉重復(fù)值

十、導(dǎo)出文件

df.to_excel(excel_writer=r’C:\users\zhoulifu\Desktop\測(cè)試.xlsx’,sheet_name=’文檔’,index=False,columns=[‘ID’,’銷(xiāo)量’,‘姓名’],encoding=’utf-8’,na_rep=0)

  • excel_writer參數(shù)指定文件路徑,導(dǎo)出時(shí)去掉索引,設(shè)置導(dǎo)出的列,指定文件編碼,na_rep缺失值填充
    writer=pd.ExcelWriter(excelpath,engine=’xlsxwirter’)

導(dǎo)出多個(gè)文件至一個(gè)文件的多個(gè)sheet;

  • 方法1:
writer=pd.ExcelWriter(excelpath,engine='openpyxl',mode='a')
用openpyxl不會(huì)刪除excel表中原有sheet,更保險(xiǎn)!
df1.to_excel(writer,sheet_name=‘表一’,index= False)
writer.save()
writer.close()
  • 方法2:
df = pd.read_excel(path,sheet_name='test3')
#寫(xiě)入到原Excel表中避免清空其他數(shù)據(jù)
book = openpyxl.load_workbook(path)   #讀取你要寫(xiě)入的workbook
#和pd.read_excel() 用于將Dataframe寫(xiě)入excel。xls用xlwt。xlsx用openpyxl
writer = pd.ExcelWriter(path,engine='openpyxl')   
##此時(shí)的writer里還只是讀寫(xiě)器. 然后將上面讀取的book復(fù)制給writer  
writer.book = book
#轉(zhuǎn)化為字典的形式
writer.sheets = dict((ws.title, ws) for ws in book.worksheets)#返回一個(gè)字典,sheet名和sheet對(duì)象組成的鍵值對(duì)
#將data寫(xiě)入writer
df.to_excel(writer,sheet_name="測(cè)試",index=False)
writer.save()
writer.close()
  • to_json
    data = df([['a', 'b'], ['c', 'd']], index=['row 1', 'row 2'], columns=['col 1', 'col 2'])
    json_columns = data.to_json(orient = "columns") # 返回結(jié)果:
    '{"col 1":{"row 1":"a","row 2":"c"},"col 2":{"row 1":"b","row 2":"d"}}'
    json_split = data.to_json(orient = "split") # 返回結(jié)果:
    '{"columns":["col 1","col 2"],"index":["row 1","row 2"],"data":[["a","b"],["c","d"]]}'
    json_records = data.to_json(orient = "records") # 返回結(jié)果:
    '[{"col 1":"a","col 2":"b"},{"col 1":"c","col 2":"d"}]'
    json_index = data.to_json(orient = "index") # 返回結(jié)果:
    '{"row 1":{"col 1":"a","col 2":"b"},"row 2":{"col 1":"c","col 2":"d"}}'
    json_values = data.to_json(orient = "values") # 返回結(jié)果:
    '[["a","b"],["c","d"]]'
    ? format()函數(shù),與lambda函數(shù)配合,可以設(shè)置:四舍五入保留小數(shù)位、轉(zhuǎn)化為百分?jǐn)?shù)、添加千位分隔符等
    保留1位小數(shù):df["A"].map(lambda x: format(x, '.1f'))
    設(shè)置百分?jǐn)?shù),并保留2位小數(shù):df["A"].map(lambda x: format(x, '.2%'))
    設(shè)置千位分隔,并保留3位小數(shù):df["A"].map(lambda x: format(x, ',.3f'))
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,797評(píng)論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,179評(píng)論 3 414
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 175,628評(píng)論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 62,642評(píng)論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,444評(píng)論 6 405
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 54,948評(píng)論 1 321
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,040評(píng)論 3 440
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 42,185評(píng)論 0 287
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,717評(píng)論 1 333
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,602評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,794評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,316評(píng)論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,045評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 34,418評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 35,671評(píng)論 1 281
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,414評(píng)論 3 390
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,750評(píng)論 2 370

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