1.導入數據源python
#導入相關庫 import pandas as pd import numpy as np import os from pandas import DataFrame,Series import re df =pd.read_csv(r'E:\work\daima\python\forestfires.csv') #打開文件
2.數據基本處理正則表達式
1)查看列名和數據類型後端
print(df.columns) #查看列名 print(df.dtypes) #查看各列數據類型
2)查看指定行列數據函數
print(df.head(20)) #查看前20行數據 df=df.loc[:,'FFMC':'rain'] #選擇FFMC到rain列全部數據
3)刪除行或列rest
df=df.drop(['wind', 'rain', 'area'],axis=1) #刪除wind,rain和area三列 df_an=df_an.loc[-(df_an['qudao']=='Total')] #刪除qudao列等於'Total'的行
4)移除重複數據orm
df_new=df.drop_duplicates(['month','day']) #移除month和day列包含重複值得行,保留第一個 df_new=df.drop_duplicates(['month'],take_last=True )#移除month列包含重複值得行,保留最後一個
5)更改列名排序
df.rename(columns={'ISI':'isi'}, inplace = True) #ISI列列名改成isi
2.描述性統計ip
1)計算某列變量頻數ci
print(df['month'].unique()) #輸出month列惟一值 print(df['month'].value_counts()) #輸出month列各變量出現頻數
2)分段統計字符串
bins=[0,10,20,30,40,50,60,70,80,90,100] group_names=['0-10','10-20','20-30','30-40','40-50','50-60','60-70','70-80','80-90','90-100'] cats=pd.cut(df['RH'],bins,labels=group_names) pd.value_counts(cats,sort=False)
3)添加一列分組列,作多維頻數統計
bins=[0,10,20,30,40,50,60,70,80,90,100] group_names=['0-10','10-20','20-30','30-40','40-50','50-60','60-70','70-80','80-90','90-100'] cats=pd.cut(df['RH'],bins,labels=group_names) df_concat=pd.concat([df,cats],axis=1,ignore_index=True) df_group=df_concat[7].groupby([df_concat[0],df_concat[6],df_concat[7]]) df_fum=df_group.agg('count')
3.缺失值處理
1)缺失值統計
a顯示有缺失值的行
df[df.isnull().values==True] #顯示有缺失值的行
b增長一列,顯示每行的缺失值
df_na=(df.isnull()).sum(axis=1) #統計每行的缺失值 df=pd.concat([df,df_na],axis=1) #df和df_na橫向拼接 df.rename(columns={0:'na_num'}, inplace = True) #更改列名 df=df.loc[df['na_num']<=5]#刪去變量值大於5的行
2)填充缺失值
a刪除含有缺失值的行(或者全爲NA的行)
df.dropna()#刪除含有缺失值的行 df.dropna(how='all')#只丟棄全爲NA的那些行
b填充固定值
train_data.fillna(0, inplace=True) # 填充 0
c填充均值
df['DC'].fillna(df['DC'].mean(),inplace=True) # 填充均值
d填充中位數
df['DC'].fillna(df['DC'].median(),inplace=True) #DC列缺失值填充爲DC列的中位數
e填充衆數
df['DC'].fillna(df['DC'].mode(),inplace=True) # 填充衆數 #循環用衆數填充每列缺失值,若衆數爲na的狀況,刪掉na features=['X', 'Y', 'month', 'day', 'FFMC', 'DMC', 'DC', 'ISI', 'temp', 'RH', 'wind', 'rain', 'area'] features_mode = {} for f in features: print (f,':', list(df[f].dropna().mode().values)) features_mode[f] = list(df[f].dropna().mode().values)[0] df.fillna(features_mode,inplace=True)
f填充上下條的數據
df['DC'].fillna(method='pad', inplace=True) df['DC'].fillna(0, inplace=True)# 前一條沒值就填充0 df['DC'].fillna(method='bfill', inplace=True) df['DC'].fillna(0, inplace=True)# 後一條沒值就填充0
g填充KNN數據
from fancyimpute import KNN features=['X', 'Y', 'month', 'day', 'FFMC', 'DMC', 'DC', 'ISI', 'temp', 'RH', 'wind', 'rain', 'area'] train_data_x = pd.DataFrame(KNN(k=6).fit_transform(df), columns=features)
4.篩選
1)條件篩選loc
df_sel=df.loc[(df['month']=='aug') & (df['DC']>=600)] #篩選month列等於aug且DC列大於600的全部行
2)篩選並給新列賦值
這個多用於區間匹配,例如若是A列(0,100],C列爲50;A列大於100 ,C列爲A列的值。
df.loc[(df['DC']>0) & (df['DC']<=100) ,'DC_na']=50 # 建立新列DC_na,DC列大於0且小於等於100,DC列爲50 df.loc[df['DC']>100,'DC_na']=df['DC']# 建立新列DC_na,DC列大於100等於原值,其餘爲NA
這裏舉一個其餘相似的例子:
有一組數據包含三列(列名爲A,B,C),如今要新增一個D列,若是A>100且5<B<7,那麼D列的值等於C列減5;若是A>100且B>=7,那麼D列的值等於C列減10,其餘狀況D列的值等於C列的值。
df['D']=df['C'] df.loc[(df['A']>100) & (df['B']>=5) &(df['B']<=7) ,'D']=df['C']-5 df.loc[(df['A']>100) & (df['B']>=7) ,'D']=df['C']-10
3)模糊篩選/精確篩選:isin(),contains()
df_sel1=df[df['day'].str.contains('fr')] # 篩選day列包含fr字符的行 df_sel2=df[df['day'].isin(['fri','mon'])] # 篩選day列等於fri或mon的行
5.替換
1)去掉字符串兩端空格
df_city['experience_new'] = df_city['experience'].map(lambda s: s.strip())#experience列中文先後端包含空格,需對改列進行分詞處理(去掉空格),賦值給新列experience_new
2)替換
#將experience_new列中的應屆畢業生替換爲1年如下 df_city = df_city.replace({'experience_new':'應屆畢業生'},'1年如下') df_city['expreienct_new']=df_city['expreienct_new'].map(lambda s:re.sub('應屆畢業生','1年如下',s))
6.提取字符串
1)分列
df['new']=df['day'].map(lambda s:re.compile(':').split(s)[0])#對df['day']列按照符號':'進行分列並提取第一個值,賦值到新列df['new']
2)搜索字符串
這個狀況不少,涉及到不少正則表達式知識。
df['xin']='U34' #增長新列,列名爲xin,爲新列賦值U34 df['zimu']=df['xin'].map(lambda s:re.compile("([0-9]+)").search(s).group()[0])#搜索字母並提取第一個值 df['shuzi']=df['xin'].map(lambda s:re.compile("[a-zA-Z]+").search(s).group()[0])#搜索字母並提取第一個值
3)若是未匹配到關鍵字,直接用group()函數會報錯
def chuli(s): jieguo=re.compile("([0-9]+)").search(s) if jieguo: jieguo=int(jieguo.group())+1 else : jieguo=0 return jieguo df['Room']=df['Cabin'].map(chuli)
7.關聯
1)兩表關聯:merge(左關聯,右關聯)
好比有如下兩個數據集
df1 客戶信息表
customer_id sex city
10084 男 北京
10085 女 上海
10086 男 廣州
10087 女 深圳
df2訂單表
order customer_id product shouru
CH001 10084 A 500
CH002 10085 B 200
CH003 10086 C 1000
CH004 10086 D 3000
a左關聯
df_merge=pd.merge(df1,df2,on='customer_id',how='left') #左關聯 print(df_merge)
注意第三四列,與EXCEL匹配的邏輯稍有不一樣。
customer_id sex city order product shouru
10084 男 北京 CH001 A 500
10085 女 上海 CH002 B 200
10086 男 廣州 CH003 C 1000
10086 男 廣州 CH004 D 3000
10087 女 深圳 NA NA NA
b根據多列進行左關聯
pd.merge(df1,df2,on=['key1','key2'],how='left')#多鍵鏈接
2)多表進行關聯
a軸向鏈接:concat()
pd.concat([df1,df2],axis=1,ignore_index=True)#df1和df2橫向拼接
b多表關聯:reduce()
from functools import reduce df_list=[df_dau,df_gmv_zx,df_dau_zx] df_zhengti=reduce(lambda left,right:pd.merge(left,right,on=['event_date','duan'],how='left'),df_list) #按照event_date,duan 從左到右對df_list中的文件進行左關聯
8.聚合(數據透視表)
相似於數據透視表,相似於sumifs(),countifs(),averageifs()等函數的效果。
1)聚合groupby()
df_group=df['DC'].groupby([df['month'],df['day']]) #根據month和day列對DC列進行聚合 df_fun=df_gorup.agg(['sum','mean','std']) #對df_group求和,均值和標準差 print(df_fun)
2)數據透視表pd.pivot_table()
這個函數比較難記,能夠參考EXCEL數據透視表去理解,index表明列,columns表明行,values表明值,aggfunc表明要對值用什麼函數,fil_value表明缺失值用0填充。
df_toushi=pd.pivot_table(df,index=['month'],columns=['day'], values=['DC'],aggfunc=[np.sum,np.mean],fill_value=0) print(df_toushi)
9.排序
按照DMC列降序,DC列升序對數據集進行排序。
df_paixu=df.sort_values(by=['DMC','DC'],ascending=[0,1])
10時間序列處理
1)csv中的時間會被讀取爲字符串,須要批量處理爲pandas可處理的時間類型
df['date']=pd.to_datetime(df['createTime']) #批量轉換createTime中的時間,並賦值到date列 df[(df['date']>='20140701')&(df['date']<='20140715')]#篩選指定時間段數據
2)時間設置
from datetime import datetime, timedelta import time today = datetime.today()#今天 yesterday_ts = time.time() - 24 * 3600#昨天 yesterday = datetime.fromtimestamp(yesterday_ts).strftime('%Y-%m-%d') #轉換爲年月日 fromtime = (today -timedelta(16)).strftime('%Y-%m-%d') #16天前,並轉化爲年月日 day_before_yesterday_ts = yesterday_ts - 24*3600#前天 day_before_yesterday = datetime.fromtimestamp(day_before_yesterday_ts).strftime('%Y-%m-