資料處理2.0
之前的在1.0版本中,我處理的是一個只有[54 rows,547columns]的比較小的資料集,當遇到較大的資料集時([197896 rows,547columns]),程式處理遇到了問題。比如:資料讀取比較緩慢,之前跑大概1-2s,後來需要將近30min才能出結果;輸出的結果檔案太大,導致python報錯無法輸出;資料集又出現了新的資料,需要進一步處理。
問題:
- 輸出檔案太大
原來的處理辦法是df = pd.read_excel、df.to_excel
報錯出現了這樣的提示:
“filesize would require ZIP64 extensions”
嘗試找了一下python怎樣壓縮檔案然後輸出,找到了這樣的方法:
參考:
得到了這樣的程式碼:
df_float = df.select_dtypes(include=['float']) converted_float =df_float.apply(pd.to_numeric,downcast='float') df_int = df.select_dtypes(include=['int']) converted_int =df_int.apply(pd.to_numeric,downcast='unsigned') df[converted_int .columns] = converted_int df[converted_float .columns] = converted_float
之後我發現:這段程式碼不僅沒有壓縮結果資料,反而使得結果檔案更大了……究竟是怎麼回事,可能得之後深究;
現在另尋辦法——我又在偶然間意外發現可以通過輸出到csv檔案得到結果,於是我總結了一個“規律”:csv檔案要比excel檔案小,因此程式碼修改為:df = pd.read_excel、df.to_csv
這樣就不會報錯了
- 新的特殊資料和解決辦法
歲數一列出現了異常值:‘歲’及空資料
解決方案:需要將異常值置為空值,即填充-1000
修改函式如下:
def convert(value,data1,data2): """ 轉換字串string1為string2 """ if isinstance(value,str): if(value.find(data1) != -1): value = value.replace(data1, data2) if value == '': value = '-1000' value = float(value) return value df['AGE_INPUT'] = df['AGE_INPUT'].apply(convert,data1 = '歲',data2 = '')
全表資料出現一個單位的作為異常值處理,填充-1000:
Units=['mmol/l','mmHg']
def DelUnits(value):
"""
刪除單位
"""
if isinstance(value,str):
for units in Units:
if value == units:
value = -1000.0
break
return value
df = df.applymap(DelUnits)
資料中出現的帶年、月、日的資料和帶有’/'的資料都作為異常資料處理,做統一化處理都填充-1000:
#全表修改/,分數等異常值為空值處理
#異常值列表
Outliers = ['/','年','月','日']
def CharConvert(value):
if isinstance(value,str):
for outlier in Outliers:
if(value.find(outlier) != -1):
value = -1000.0
break
return value
df = df.applymap(CharConvert)
在應用中發現當資料格式為X年X月X日時,讀入DataFrame後存入的是一個整數,經過試驗發現1900年1月1日對應的數是1,此後的日期對應的數依次遞增,而1900年之前的日期則以字串的方式(X/X/X)存入DataFrame,因此對1900之前的日期的處理可以歸結成對/的處理 ,而對1900之後的日期的處理只能將dataframe裡超出1000的資料(即1000作為閾值,視具體情況而定)視作異常值,這樣基本不會影響正常的資料,還去除了表中的日期(表裡的日期都是2000年以後)。為了方便,在刪除單位遍歷全表時就達成對日期的處理(注意保留ID一列不被修改),程式碼修改如下:
#全表處理單位和日期異常值
Units=['mmol/l','mmHg']
#先保留ID
IDtemp = df[df.columns[0:3]]
def DelUnits(value):
"""
刪除單位
"""
if isinstance(value,str):
for units in Units:
if value == units:
value = -1000.0
break
else:
if value > 1000:
value = -1000.0
return value
df = df.applymap(DelUnits)
df[df.columns[0:3]] = IDtemp
使用正則表示式處理>和<,出現了<X↓
形式的資料,原來的函式不好處理,程式碼如下:
global pattern_s1
global pattern_s2
pattern_s1 = re.compile('<(\d?\.?\d+)')
pattern_s2 = re.compile('>(\d?\.?\d+)')
#全表修改<,>
def DataConvert(value):
if isinstance(value,str):
p = re.findall(pattern_s1,value)
if p == []:
p = re.findall(pattern_s2,value)
if p != []:
value = float(p[0])
return value
df = df.applymap(DataConvert)
更新後的程式碼如附件