第一時間接收最新Python干貨! 
早起Python推薦搜索
Python Pandas 數(shù)據(jù)分析 大家好,關(guān)于Python數(shù)據(jù)分析的工具我們已經(jīng)講了很多了,相信一直關(guān)注的讀者對于Pandas、NumPy、Matplotlib的各種操作一定不陌生,今天我們就用一份簡單的數(shù)據(jù)來學(xué)習(xí)如何使用Python進(jìn)行數(shù)據(jù)分析,本文主要涉及下面三個部分:
雖然本文使用的數(shù)據(jù)(醫(yī)學(xué)相關(guān))不會出現(xiàn)在你平時的工作學(xué)習(xí)中,但是處理的過程比如導(dǎo)入數(shù)據(jù)、缺失值處理、數(shù)據(jù)去重、計(jì)算、匯總、可視化、導(dǎo)出等操作卻是重要的,甚至還教你如何將程序打包之后對于重復(fù)的工作可以一鍵完成!因此我十分建議從文末獲取數(shù)據(jù)邊敲邊思考,畢竟像這樣配有詳細(xì)注釋的代碼講解并不多~ 今天分享的案例來源于一個著名的實(shí)驗(yàn)Cell Counting Kit-8。首先我們來看下原始數(shù)據(jù):  1. 去除各組所有重復(fù)中的最大值和最小值 2. 所有數(shù)據(jù)根據(jù)D0的對應(yīng)分組進(jìn)行標(biāo)準(zhǔn)化 3. 計(jì)算各組數(shù)據(jù)的均值和標(biāo)準(zhǔn)差表格:均值匯總表和均值-標(biāo)準(zhǔn)差匯總表 4. 繪制折線圖所以我們需要的結(jié)果應(yīng)該是:在自己的桌面上建一個文件夾命名data ,將原始數(shù)據(jù)data.xlsx 放進(jìn)去,之后運(yùn)行完程序后文件夾會新增3個文件:
而這三個文件就是我們需要的結(jié)果
均值匯總表 
均值-標(biāo)準(zhǔn)差匯總表 
折線圖 
現(xiàn)在我們就來講解如何實(shí)現(xiàn)。 首先導(dǎo)入庫并調(diào)用函數(shù)獲取桌面文件夾路徑并寫在全局 import pandas as pd import matplotlib.pyplot as plt import os import random def GetDesktopPath(): return os.path.join(os.path.expanduser('~'), 'Desktop')
path = GetDesktopPath() + '/data/'
導(dǎo)入原始數(shù)據(jù)并去除缺失值
dat = pd.read_excel(path + 'data.xlsx', sheet_name=0, header=None, index_col=0) dat = dat.dropna(how='any', axis=0)

獲取重復(fù)次數(shù),分組個數(shù)和天數(shù)。原始數(shù)據(jù)有6天、5組、5次重復(fù),雖然也可以直接使用這三個數(shù)據(jù),但以后的實(shí)驗(yàn)這三個可能會更改,為了讓代碼能夠復(fù)用,最好不要寫死 # 獲取分組個數(shù) ngroup = dat.index.value_counts().shape[0] # 獲取列數(shù)即重復(fù)次數(shù) nrep = dat.shape[1] # 獲取天數(shù)(操作的批次數(shù))即用總行數(shù)除以組數(shù),用整除是為了返回int nd = dat.shape[0] // ngroup
去掉極大值和極小值。這里用的解決辦法是逐行升序排序,然后去掉第一個和最后一個數(shù)據(jù),可以用apply+lambda處理 df = dat.apply(lambda x: sorted(x)[1:nrep - 1], axis=1)
df = df.to_frame(name='total') for i in range(nrep - 2): df[f'{i + 1}'] = df['total'].str[i]
df.drop(columns=['total'], inplace=True)
用匿名函數(shù)排序返回的是Series的升序列表,須有轉(zhuǎn)換回DataFrame再拆成三列,最后去掉原來返回那一列即可。因此有了如上代碼 
在常規(guī)列中添加分組信息和批次信息,便于后續(xù)做匯總表 df['group'] = df.index
day_lst = [] for i in range(nd): day_lst.append(f'Day{i}') # 用列表推導(dǎo)式做列表內(nèi)元素重復(fù)并添加新列 df['day'] = [i for i in day_lst for _ in range(ngroup)]
效果如圖:

根據(jù)D0的各組均值對所有數(shù)據(jù)標(biāo)準(zhǔn)化,可以簡單理解為DO批次5個組去除兩個極值后各求平均值,這5個批次的5個組各自除于D0對應(yīng)組的均值) # 根據(jù)組數(shù)取出D0的所有行數(shù),然后按行求均值,會自動忽略文本信息 mean_lst = df.iloc[0:ngroup, :].mean(axis = 1).tolist()
# 由于接下來要按行進(jìn)行迭代,且索引的分組信息已經(jīng)有一個新列來表述,這里重置索引方便迭代 df.reset_index(drop=True, inplace=True)
# 迭代的內(nèi)容看起來復(fù)雜實(shí)際上不難 # 本質(zhì)上就是將迭代行的數(shù)據(jù)和D0對應(yīng)分組均值相除 for index, i in df.iterrows(): df.iloc[index, 0:nrep - 2] = i[0:nrep - 2] / mean_lst[index % ngroup]

標(biāo)準(zhǔn)化結(jié)束后即可獲取均值和標(biāo)準(zhǔn)差
# 同樣mean和std均會忽略非數(shù)值列 # 謹(jǐn)慎一點(diǎn)用df['mean'] = df.iloc[:, 0:nrep - 2].mean(axis=1)也可以 df['mean'] = df.mean(axis=1) df['std'] = df.std(axis=1)
# 獲取最后四列 results = df.iloc[:, -4:]

制作數(shù)據(jù)透視表并導(dǎo)出 # 用round保留4位有效數(shù)字 tb1 = pd.pivot_table(data=results, index='group', columns='day', values='mean').round(4)
tb2 = pd.pivot_table(data=results, index='group', columns='day', values=['mean', 'std']).round(4)
tb1.to_excel(path + '/result(mean).xlsx', index=True, header=True)
tb2.to_excel(path + '/result(mean+std).xlsx', index=True, header=True)
在Jupyter Notebook呈現(xiàn)結(jié)果如下,在Excel的呈現(xiàn)如本文開頭所示

利用matplotlib畫圖,補(bǔ)充兩個細(xì)節(jié),如果在Jupyter Notebook希望出圖需要加上如下代碼 如果有中文字符需要呈現(xiàn)也同樣需要用代碼設(shè)置
plt.rcParams['font.sans-serif'] = ['SimHei']
匯總表的索引(組名)可以用做圖像的標(biāo)簽。而顏色和折線上標(biāo)記樣式所用的測量是根據(jù)所需的個數(shù)隨機(jī)無放回抽樣 group_lst = tb1.index.tolist() colors = ['b', 'g', 'r', 'c', 'm', 'y'] color_lst = random.sample(colors, ngroup) markers = ['.', ',', 'o', 'v', '^', '<', '>', '1', '2', '3', '4', 's', 'p', '*', 'h', 'H', '+', 'x', 'D', 'd'] marker_lst = random.sample(markers, ngroup)
最后的畫圖代碼:
# 設(shè)置畫布大小 plt.figure(figsize=(8, 5))
for i in range(ngroup): plt.plot(tb1.iloc[i, :].tolist(), f'{color_lst[i]}{marker_lst[i]}-', lw=2)
plt.xticks(range(0, nd), day_lst, fontsize=18) plt.ylabel('Relative Cell Amount', fontsize=18) plt.legend(group_lst, loc='best', fontsize=12) # 讓圖像的顯示分布正常 plt.tight_layout() # 保存一定要在調(diào)用展示之前 plt.savefig(path + '/折線圖.png') plt.show()
首先在命令行使用pip安裝pyinstaller
|