最近在參加學(xué)習(xí)開(kāi)源社區(qū)Datawhale組織的"21天精通Pandas學(xué)習(xí)",其中有個(gè)練習(xí)題做起來(lái)很有意思,練習(xí)題本身很簡(jiǎn)單,我在這里稍微引申一下讓大家體會(huì)一下Pandas處理數(shù)據(jù)功能的靈活和強(qiáng)大。
題目如下:
提供2020-04-12到2020-12-31日的美國(guó)新冠病毒(COVID-19)各個(gè)州的統(tǒng)計(jì)數(shù)據(jù),原始數(shù)據(jù)是每一天為一份csv文件,每份csv文件包含了各個(gè)州的報(bào)告感染人數(shù),死亡人數(shù)等數(shù)據(jù),如下:
-
原始數(shù)據(jù):以日期命名的csv文件, 部分截圖
image.png -
每份文件包含數(shù)據(jù), 以其中一份為例:
image.png
每份文件的格式都相同,包含了所有州當(dāng)天的數(shù)據(jù)統(tǒng)計(jì)情況。
現(xiàn)在要求從每份文件中提取紐約州的'Confirmed','Deaths','Recovered','Active'四項(xiàng)數(shù)據(jù)數(shù)據(jù),并重新組成一個(gè)新的DataFrame,以每份文件的文件名,即日期為索引,四項(xiàng)數(shù)據(jù)中每一項(xiàng)為一列。
其實(shí)如果就幾份文件,直接新建一個(gè)新的表格,在 CTRL + C在 CTRL + V拉到了。但是這里有將近300份表格,不上辦公自動(dòng)化要死人的。
用python,一個(gè)循環(huán)語(yǔ)句全部搞定!
import pandas as pd
import numpy as np
import os
path = './covid_19_daily_reports_us/'
print(os.listdir(path)[:3]) # 打印前五份文件查看
print('There are {} reports need processed'.format(len(os.listdir(path))))
>>>
['04-12-2020.csv', '04-13-2020.csv', '04-14-2020.csv']
There are 264 reports need processed
下面為代碼的主體部分:
state = 'New York'
need_col = ['Confirmed','Deaths','Recovered','Active']
def file_process(f):
f_index = [f.split('.')[0]] # 注意index必須要是一個(gè)列表的形式
f_df = pd.read_csv(path + f)
new_df = f_df[f_df['Province_State'] == state][need_col]
new_df.index = f_index
return new_df
# 使用一個(gè)文件調(diào)試,看看是否能夠正確的提取信息
file_process('05-01-2020.csv')

OK,可以正確輸出需要的內(nèi)容。
上面的代碼,主要部分就是一個(gè)函數(shù),用來(lái)從每份文件中提取文件名作為新的DataFrame的索引,然后扣取需要的內(nèi)容。在這里注意我們將需要提取的州(New York)和內(nèi)容('Confirmed','Deaths','Recovered','Active')定義在函數(shù)體的外部,這樣做是防止將來(lái)有人更改需求的是時(shí)候可以不用重寫函數(shù),只更改外部的變量即可。例如現(xiàn)在老特跑過(guò)來(lái)跟你說(shuō)我想看看佛羅里達(dá)州的情況,不要死亡人數(shù),只看看確診人數(shù),這時(shí)只要在外面重新定義state和need_col即可。這樣做也體現(xiàn)了代碼中函數(shù)特征:可以高度復(fù)用,但同時(shí)和程序的其他部分保持低耦合的關(guān)系。
有了這個(gè)函數(shù),下面一個(gè)循環(huán)搞定所有文件:
# 讀取所有樣本
df1 = file_process('04-12-2020.csv')
for file in os.listdir(path)[1:]:
df1 = pd.concat([df1, file_process(file)])
df1

OK,搞定!下面我們?cè)谝暌幌?,需求更改?br>
現(xiàn)在的原始數(shù)據(jù)是按照日期來(lái)統(tǒng)計(jì),現(xiàn)在要求按照州來(lái)組織每份文件。即一份文件為一個(gè)州,包含所有天的'Confirmed','Deaths','Recovered','Active'數(shù)據(jù),同時(shí)以州名為文件名。
上面我們已經(jīng)完成了紐約州的統(tǒng)計(jì),稍微一思考,也就是把這個(gè)程序在每個(gè)州上運(yùn)行一遍即可:
- 獲取所有州的州名形成一個(gè)列表
- 遍歷這個(gè)列表,將每個(gè)州取出重復(fù)之前的動(dòng)作,即遍歷所有文件,取出需要的內(nèi)容,之后在將取出的內(nèi)容寫入csv文件,以州名命名文件名即可
for state in df['Province_State']:
df1 = file_process('04-12-2020.csv')
for file in os.listdir(path)[1:]:
df1 = pd.concat([df1, file_process(file)])
df1.to_csv('./state_data/' + state + '.csv')
也就是多一個(gè)循環(huán)的事!
OK,運(yùn)行完之后,我們可以看到在定義的文件夾下程序?qū)懞玫奈募?/p>

隨便打開(kāi)一份查看:

OK,沒(méi)有問(wèn)題,搞定!
這就完了嗎?沒(méi)有,本期我是想給大家介紹一個(gè)非常好用的工具——進(jìn)度條,tqdm!
大家有沒(méi)有發(fā)現(xiàn)程序在跑循環(huán)的時(shí)候,有時(shí)候因?yàn)閿?shù)據(jù)量比較大,等待時(shí)間會(huì)比較長(zhǎng)。有時(shí)候會(huì)有一種程序掛掉的錯(cuò)覺(jué)。這時(shí)候如果有個(gè)進(jìn)度條循環(huán)程序跑到哪里了,還剩多少就nice了!tqdm這個(gè)工具就完美的解決了這個(gè)問(wèn)題。使用也超級(jí)簡(jiǎn)單,在可迭代對(duì)象前面加上即可!
# 加上可視化進(jìn)度條
from tqdm import tqdm # 先導(dǎo)入tqdm
for state in tqdm(df['Province_State']): # 將可迭代對(duì)象封裝到tqdm即可
df1 = file_process('04-12-2020.csv')
for file in os.listdir(path)[1:]:
df1 = pd.concat([df1, file_process(file)])
df1.to_csv('./state_data/' + state + '.csv')
這里沒(méi)有運(yùn)行的效果的截屏展示,網(wǎng)上找了一張圖,感受一下!

效果完美!這也是為什么要學(xué)習(xí)Python的原因,因?yàn)橛型晟曝S富的社區(qū),很多人開(kāi)發(fā)了很多好用的工具,避免了重復(fù)造輪子。

