[工作必備]pandas資料分析處理52個常用技巧, 建議收藏!

2021-04-25 07:00:14

python中的第3方工具包pandas功能強大, 日常工作中比如篩選、排序、計算、透視、vlookup、分類彙總等excel常用操作用pandas也能輕鬆實現;
本文精心整理的pandas資料處理與分析的52個技巧, 100多個知識點, 掌握這些,處理資料不再是難事!

零基礎學習python資料分析, 建議安裝anaconda, 可通過下面網址安裝 : 清華映象

配套相關基礎課程, 理論+實踐: 歡迎訂閱 →

  • 1 匯入工具包
# pandas 和numpy是兩個基礎的工具包
import numpy as np
import pandas as pd
# matplotlib seaborn是作圖工具包
import matplotlib.pyplot as plt
import seaborn as sns
# 通過os設定預設路徑
import os
os.chdir('C:/Users/使用者/Desktop/')  # 桌面的路徑
# 圖表中文顯示問題
plt.rcParams['font.sans-serif']=['SimHei'] #用來正常顯示中文標籤
plt.rcParams['axes.unicode_minus']=False #用來正常顯示負號
# 不顯示預警
import warnings  
warnings.filterwarnings('ignore')
  • 2 spyder中快捷鍵
# 註釋、取消註釋
Ctrl+1
# 塊註釋 / 取消塊註釋  
Ctrl+4/5
# 從當前遊標所在行開始執行
F9
  • 3 讀取excel資料
# 讀取檔案
df = pd.read_excel('檔案.xlsx')
# 讀取檔案同時篩選需要的列
df = pd.read_excel('檔案.xlsx')[['','']] # 讀取並篩選幾列
# 讀取特定的工作表
df = pd.read_excel('檔案.xlsx',sheet_name='明細') # 讀取某個sheet表
# with方法讀取
with pd.ExcelFile('path_to_file.xls') as xls:
    df1 = pd.read_excel(xls, 'Sheet1')
    df2 = pd.read_excel(xls, 'Sheet2')
  • 4  讀取csv或者txt
# 分隔符: \s 表示空白字元; \s+多個空白字元; \r回車; \n換行; \t水平製表符; \v垂直製表符
df = pd.read_csv('檔案.txt',sep='\s+',error_bad_lines=False)    
  • 5 批次讀取同一資料夾下檔案方式1
for root, dirs, files in os.walk('.',topdown=False):
    print(files)
num = len(files)   # 獲取檔案個數
data = pd.DataFrame()  # 定義一個空的dataframe
# 遍歷所有檔案
for i in range(num):
    datai = pd.read_excel('./%s' %files[i])   
    datai_len = len(datai)
    data = data.append(datai)   # 新增到總的資料中
    print('檔案%i列, 第%i個表,讀取%i行資料,名稱:%s'%(len(data.columns),i,datai_len,files[i]))     # 檢視是否全部讀取,格式是否出錯
    
data.reset_index(drop=True,inplace=True)
  • 6 批次讀取同一資料夾下的檔案方式2
# 匯入工具包
import pandas as pd
import numpy as np
import os

# 路徑
path = 'd:/檔案路徑/'

# 檔案列表
files = []
for file in os.listdir(path):
    if file.endswith(".csv"):
        files.append(path+file)

# 定義一個空的dataframe
data = pd.DataFrame()  

# 遍歷所有檔案
for file in files:
    datai = pd.read_csv(file,encoding='gbk')
    datai_len = len(datai)
    data = data.append(datai)   # 新增到總的資料中
    print('讀取%i行資料,合併後檔案%i列, 名稱:%s'%(datai_len,len(data.columns),file.split('/')[-1]))     
    # 檢視是否全部讀取,格式是否出錯
# 重置索引    
data.reset_index(drop=True,inplace=True)
  • 7 批次讀取同一資料夾下得檔案方式3(當txt檔案不規範,讀取會丟失資料或檔案太大時)
# 迴圈讀取資料
n = 1
for file in files:    
    with open(file, 'r',encoding='gbk') as f_input:
        lisi= []
        for line in f_input:
            lisi.append(list(line.strip().split('|')))
            
    datai = pd.DataFrame(lisi)
    datai2 = guolv(datai)
    data = data.append(datai2)
            
    print('讀取第%i個檔案,件名%s,檔案%i行,文%i列.處理後檔案%i行,%i列' %(n,file,datai.shape[0],datai.shape[1],datai2.shape[0],datai2.shape[1]))
    n = n + 1
  • 8 檔案匯出,放在同一工作簿
with pd.ExcelWriter('檔案.xlsx') as writer:
    df1.to_excel(writer, sheet_name='檔案1')
    df2.to_excel(writer, sheet_name='檔案2')
  • 9 檔案匯出, 分組匯出放在同一工作簿
writer = pd.ExcelWriter('檔案.xlsx')
for name , group in df.groupby('名稱'):
    group.to_excel(writer,sheet_name=name,index=False)
  • 10 檔案匯出, 分組匯出, 放在不同工作簿
for name , group in df.groupby('名稱'):
    group.to_excel(name+'.xlsx',index=False)
  • 11 獲取當前時間
import time
tim = time.strftime("%Y-%m-%d%H%M%S", time.localtime()) 
  • 12 儲存圖片解析度設定
plt.savefig('名稱.png',dpi=150)  
  • 13 資料檢視
df.describe()   # 描述統計
df.info()    # 基本資訊
df.dtypes    # 列格式型別
df.head(2)    #前n行
df.tail(2)    #後n行
df.shape    #維度
df.index  #索引
df.columns  #列名
df.sample(10)   #隨機抽樣
df.resample()  #隨機抽樣
  • 14 行列處理(刪除,排序)
# 刪除列
del df['變數名']
df.drop('變數名',axis=1,inplace=True)
# 刪除行
df.drop('c')
# 更改列名
df.columns= ['var1','var2','var3']  # 列名的個數 = 欄位個數
df.rename(columns = {'名稱前':'名稱後'},inplace=True)   # columns 不能少
# series中改列名
s.rename('名稱',inplace=True)
# 調整列的順序
df1 = df1[['var1','var2','var3']]
# 調整行的順序
df2 = df1.reindex(['a','b','c','d','e']) # 返回一個新的DataFrame,按新的索引進行排序
  • 15  缺失值(檢視,替換,計數)
# 判斷是否是缺失值
df.isnull()  #不能省略括號
df.notnull()
# 計算缺失值個數
s.isnull().value_counts()
# 每列缺失值個數
df.isna().sum()  # 缺失值個數

# 填充缺失值
df['A'].fillna('缺失資料',inplace=True)  
data1.fillna(method='pad')   # 類似於excel中用上一個單元格內容批次填充
  
# 刪除指定列包含缺失值的行
data.dropna(subset=["C"],inplace=True)    # []不能少
data.dropna(how="all")   # 刪除全為空的行
data.dropna(thresh=2)    #刪除有效資料小於2的資料

# 缺失值個數並排序
df.isnull().sum().sort_values(ascending=False).head()
  • 16 重複值(檢視,刪除)
# 不重複項
df['A'].unique()  
df['A'].nunique() #檢視不重複值個數
df['A'].unique().tolist()   # 轉list 
df['A'].value_counts()  # 計數
# 去重
set(data2['名稱'])

# 檢視重複項,返回True False
df.duplicated()  
# 檢視重複的資料
data4 = data3[data3.duplicated(subset='var1',keep=False)]  

# 刪除重複項
df.drop_duplicates(['var'],inplace=True)
# 按兩列去重
data.drop_duplicates(subset=['A','B'],keep='first',inplace=True)  
# 分組計算不重複項個數
result = df.groupby(['var1','var2']).agg({'var3':'nunique','var4':['min','max']})
  • 17 修改格式(格式轉換, 百分比, 格式判斷)
# 改變列的格式(文字型數值改成數值型數值)
df['var1'] = df['var1'].astype('int')  # errors = 'ignore'
df['var1'] = df['var1'].astype(np.float)
# 多列轉換
df[['user_id','merchant_id','coupon_id']]=df[['user_id','merchant_id','coupon_id']].astype(str)  
df.infer_objects()  # 根據資料特徵自動轉換

# 百分比格式
data['B_per%'] = data['B_per'].apply(lambda x: '%.2f%%' % (x*100))

# 判斷格式,是否為字串
data['var'].apply(lambda x:isinstance(x,str))
  • 18 普通篩選
# loc篩選:選擇符合條件的行
df.loc[df["grade"] == "B"].head()

# 選擇符合條件的行和特定的列
df.loc[df["grade"] == "B", ["member_id", "grade"]].head()
# 選擇符合條件的行和特定的列,並排序
df.loc[df["grade"] == "B", ["loan_amnt", "grade"]].sort(["loan_amnt"])
# 多條件篩選
df.loc[[(df["gradd"]=="B") & (df["loan_amnt"]>5000), ["member_id", "term" ]].head()
# 反選
data[~((data.釋出時間.isnull()) & (data.實際首試日期 < '2018-11-1'))]
# 反轉行
df.iloc[::-1, :] 
  • 19 邏輯判斷後篩選
# isin篩選
df["A"].isin([1,2,3])
# 多條件
df[(df.AAA <= 6) & (df.index.isin([0, 2, 4]))]
# loc和isin組合 
df.loc[df['sepal_length'].isin([5.8,5.1])]
# 字串isin
df.loc[df['grade'].isin(['北京','上海'])]
# 字串開頭
df[df['A'].str.startswith('北京')]

# contains篩選
df[df['商品名稱'].str.contains("四件套")]
# 多個篩選
df_re =df[df['公司'].str.contains('公司A||公司B')]
# 篩選含特殊字元的
df[df['產業線'].str.contains('\?')] 
# 多條件篩選
data[(data['var1'].str[0] == 'M')&(data['var2'].apply(lambda x : str(x)[0] == '8'))]

# 索引特殊用法
df[[i.endswith('A') for i in df.index]] 

# 按字串長度篩選
data = df[df['名稱'].str.len()>5]

# 按字串開頭篩選
df[df['名稱'].str[0] == 'M']

# 篩選列
data = data.loc[:,~(data.columns.str.contains('集團'))]

# 篩選前幾個最大值
data = df.iloc[df['名稱'].nlargest(3).index]

# 篩選由漢字開頭的資料
df = df[df['名稱'].str.contains(r'^[\u4e00-\u9fa5]')]

# 日期不是索引時, 按日期篩選 
data[data['時間'].apply(lambda x: x.year == 2019)]  
data[data['時間'].apply(lambda x: x.strftime('%Y%m')=='202008')]
  • 20 分組後篩選
# 分組後篩選前2個
df2 = df1.groupby(['class']).head(2)

# 分組後篩選第2條或者倒數第2條資料
df1.groupby('class').apply(lambda i:i.iloc[1] if len(i)>1 else np.nan)
df1.groupby('class').apply(lambda i:i.iloc[-2] if len(i)>1 else np.nan)

# 分組後按條件篩選
data.groupby('var1').filter(lambda x: len(x[x['var2']=='A'])>=1)
data.groupby('公司編碼').filter(lambda x:len(x)!=3)

# groupby篩選方法1(先分組,然後篩選另一個變數中最小值)
df.loc[df.groupby('AA')['BB'].inxmin()]
#groupby篩選方法2:(先排序,分組,然後篩選每一組中的第一個)
df.sort_values(by='BB').groupby('AA',as_index=False).first()
# groupby篩選方法3:groupby與apply結合
df.groupby('aa').apply(lambda x :  x['BB'][x['cc'].idxmax()]

# 分組並排序
df[['A','B']].groupby('A').mean().sort_values('B',ascending=False).head()
  • 21 替換
# 單個替換
df['判斷'].replace(['B','C'],np.nan,inplace=True)   #支援正規表示式
# 多個替換
data['var'].replace(['A','B'],['a','b'],inplace=True)
# loc原地替換
df1.loc[df['sex']=='female', 'sex'] = 1
df1.loc[df['sex']=='male', 'sex'] = 0

# 字典
df.replace({'female':1, 'male':0})
# 適合二分法
df1['sex'] = df1['sex'].map(lambda x:1 if x=='female' else 0)
# apply
df_zb['var'] = df_zb['var'].apply(lambda x: x[:-1] if x[-1].isalpha() else x)
data3['var'] = data3['var'].apply(lambda x: x[:-1] if x[-1] == 's' else x)

# np.where
data['var'] = np.where(data['var'] == ' ',0,data['var'])
  • 22 字串處理
print('我的名字是%s,今年%i歲,體重%.2f'%('小明',20,70.1))
# 去除空格,改變大小寫
df['term'] = df['term'].map(str.strip)  #去除左右兩邊的空格,strip後面是否帶括號
df['term'] = df['term'].str.strip()
df['term'] = df['term'].map(str.lstrip)  #去除左邊的空格
df['term'] = df['term'].map(str.rstrip)  #去除右邊的空格
df['term'] = df['term'].map(str.upper)  # 改成全部大寫
df['term'] = df['term'].map(str.lower) # 改成全部小寫
df['term'] = df['term'].map(str.title) # 改成首字母大寫

# 去掉所有空格
data = data.applymap(lambda x: x.strip() if isinstance(x,str) else x)
  • 23 字串判斷
# 判斷是否為某一特定格式
df['emp_length'].apply(lambda x: x.isalpha())   #是否為字母
df['emp_length'].apply(lambda x: x. isalnum ())  #是否全未數位或者字母
df['emp_length'].apply(lambda x: x. isdigit ())  #是否為數位
  • 24  字串拆分
s.str.split('_')  # 拆分,結果是列表
s.str.split('_').str.get(1)   # 拆分後取第一個,可用於生成新變數
s.str.split('_').str[1]       # 拆分後取第一個,可用於生成新變數
s.str.split('_', expand=True) # 拆分,並展開成多列
s.str.split('_', expand=True, n=1)   # 按第一個拆分
s.str.rsplit('_', expand=True, n=1)  # 按最後一個拆分
data['var'] = data['var'].str.split('?',expand=True)[0]
  • 25 索引
# 把列變成索引
df.set_index('時間',inplace=True, drop = False)  
df.set_index(['r','s'], inplace = True) # r為一級,s為二級

# 取消層次化索引,將索引變回列
df.reset_index(inplace=True)
df.reset_index(drop=True,inplace=True,level = None)

# 按索引排序
df.sort_index(inplace=True,ascending=False)

# 更新索引(行、列都可以修改)
df2 = df1.reindex(['a','b','c','d','e']) # 返回一個新的DataFrame,按新的索引進行排序
df2 = df1.reindex(['a','b','c','d','e'],  fill_value=0) 

# 多級索引問題(索引可以在行,也可以在列)
df.index.names=['型別','供應商']  # 取名稱
df.columns.names=['型別','日期']  # 取名稱
df1 = df.swaplevel('型別','日期',axis=1)  #調整多級索引次序
df1 = df.sort_index(level=0, axis=1, ascending=True,sort_remaining=False)   # sort_remaining 預設是True
df1 = df.sum(axis=1,level='型別')  # 通過索引對多列進行求和
  • 26 排序
# na_position對NaN值的處理方式,可以選擇first和last兩種方式
df.sort()   
# 單列排序
df.sort(["loan_amnt"],ascending=False)  # 降序
# 多列進行排序,加入一個列表
df.sort(["loan_amnt","int_rate"],ascending=False)
# 升序排列後選擇前10
df.sort(["loan_amnt"],ascending=True).head(10)
# 自定義排序
df.sort_values(by=['日期','型別','距離'],ascending=True,inplace=True,na_position = 'last')   
# 索引排序
df.sort_index(inplace=True)
  • 27 日期
# 設定成日期格式
df['建立日期'] = pd.to_datetime(data_final['建立日期'],format='%Y/%m/%d')
# 設定為日期索引
df.set_index('訂單提交時間',inplace=True)

# 日期索引排序
df.sort_index(inplace=True,ascending=False)
# 日期索引的篩選
df_2019 = df['2019']  # 日期索引可以直接這樣篩選  
df['2019-01']  #按月篩選
df['2019-03-12':'2019-03-12'] #篩選某一天資料

# 改變顯示頻率(只針對日期索引)
df = df.to_period('M')  # 針對索引,關鍵步驟  Q 季度 Y年 D天

# 計算時間間隔
data['間隔天數'] = list(map(lambda x: x.days, pd.to_datetime('today') - data['生產時間']))
df['天數'] = df['天數'].apply(lambda x: x.days)

# 單獨表示間隔天數
from datetime import timedelta
aDay = timedelta(days=1)

# 時間物件格式化
df['DATE'] = [datetime.strftime(x,'%Y-%m-%d') for x in df['DATE']]

# 時間分組後計算
final = data.groupby(data['訂單時間'].apply(lambda x: x.strftime('%Y%m')))['總價'].sum()/10000
data.groupby(data['日期'].apply(lambda x: datetime.strftime(x,'%Y-%m-%d')))['var'].count()
data.set_index('日期').groupby('供應商')['數量'].rolling('7D').sum().reset_index()
final1 = data.groupby([data.to_period('Q').index,'var']).apply(lambda g: np.average(g['var2'], weights=g['模次'])).reset_index()

# 當前時間
import time
starttime = time.time()

# 當前日期
tim = time.strftime("%Y-%m-%d%H%M%S", time.localtime())

# pd.date_range  時間戳  pd.period_range 時間週期  pd.timedelta_range  時間間隔
datelist = pd.date_range('2020/11/21', periods=5)
datelist = pd.date_range('2020/11/21', periods=5,freq='M')
# 生成的資料是每月月初
index= pd.date_range('2019/02/01', periods=23,freq='MS')
pd.date_range('2017-01-01 01:00:00', '2017-01-01 02:00:00', freq= '5min')

# 當前日期前3天
import pandas as pd
from datetime import datetime
import time
lis = pd.date_range(end='2021-4-21',periods=3)
str_lis = [datetime.strftime(x,'%Y-%m-%d') for x in lis]
lis = pd.date_range(end=time.strftime("%Y/%m/%d"),periods=3)
str_lis = [datetime.strftime(x,'%Y-%m-%d') for x in lis]
  • 28 判斷是否為假期
import datetime
import chinese_calendar
demo_time = datetime.date(2018, 10, 2)
# 判斷是否是節假日
data_is_holiday = chinese_calendar.is_holiday(demo_time)  # True
# 判斷某日是否工作日
data_is_workday = chinese_calendar.is_workday(demo_time)  # False
  • 29 資料分組
# 方法1
data['for_m'] = pd.cut(data['fortune_x'],[0,50,70,500],labels = ['財低','財中','財高'])
# 方法2
df = pd.DataFrame({'value': np.random.randint(0, 100, 20)})
labels = ["{0} - {1}".format(i, i + 9) for i in range(0, 100, 10)]
df['group'] = pd.cut(df.value, range(0, 105, 10), right=False, labels=labels)
  • 30 多表合併
# 預設縱向連線,產生新的座標軸   
df = pd.concat([df1,df2],ignore_index=True)  

# merge 合併
pd.merge(left,  right,  left_on="lkey",  right_on="rkey",suffixes=("_left",  "_right"))
pd.merge(df, df, left_on=['','',''], right_on=['','',''], suffixes=('',''))

# append 表頭一致的多張表,進行連線(上下連線)
df1.append(df2).append(df3)

# combine_first
資料填補.有兩張表left和right,一般要求它們的表格結構一致,資料量也一致,使用right的資料去填補left的資料缺漏, 如果在同一位置left與right資料不一致,保留left的資料
df1.combine_first(df2)
  • 31 常用函數
count()非空觀測數量  
sum()所有值之和      
mean()所有值的平均值   
median()所有值的中位數
mode()值的模值       
std()值的標準偏差    
var()方差             
min()所有值中的最小值  
max()所有值中的最大值 
abs()絕對值          
prod()陣列元素的乘積  
cumsum()累計總和     
cumprod()累計乘積     
skew()偏斜          
kurt()峰度           
quantile()分位數
apply()通用申請       
cov()協方差         
corr() 相關係數
  • 32 描述性統計
df.describe(include=['object'])    #object - 彙總字串列  number - 彙總數位列 all - 將所有列彙總在一起(不應將其作為列表值傳遞)
df.describe().round(2)   # 只保留兩位小數
df.describe().round(2).T   #只保留兩位小數並轉置
df.groupby('性別').describe().unstack()
df.groupby('性別')['身高'].describe().unstack()
df.round(3)  # 資料可以取消科學計數法?
df = df.round(0)   # 都改為整數
# 保留2位小數
df['a']=df['mean'].round(decimals=2) 
df['b']=df['mean'].map(lambda x:("%.2f")%x) 
df['c']=df['mean'].map(lambda x:format(x,".2%"))
description = [data.min(), data.max(), data.mean(), data.std()]  # 依次計算最小值、最大值、均值、標準差
description = pd.DataFrame(description, index = ['Min', 'Max', 'Mean', 'STD']).T  # 將結果存入資料框
print('描述性統計結果:\n',np.round(description, 2))
  • 33 資料預覽
# 在cmd中安裝
pip install pandas-profiling   
import  pandas_profiling
pro = pandas_profiling.ProfileReport(data1)
pro.to_file('output_file.html')
  • 34  變化百分比
# 元素變化百分比 每個元素與其前一個元素進行比較,並計算變化百分比
df.pct_change() 
  • 35 協方差
# 協方差,cov用來計算序列物件之間的協方差
s1.cov(s2)
df['a'].cov(df['b'])
  • 36 相關性
# 相關性,pearson(預設),spearman和kendall之間的相關性
df['a'].corr(df['b'],method ='spearman')
print (frame.corr())
  • 37 排名
s.rank() 或者 df.rank()  
# (axis=0)或列(axis=1)  
#  ascending=True 正向排名或者反向排名
#  method (average :並列組平均排名,min :組中最低排名,max :組中最高等級,first :按在陣列中出現的順序分配等級)
  • 38 分組計算
# 多組運算
df.groupby(['班級','性別'])['身高'].agg([np.sum,np.mean,np.std])
df.groupby(['班級','性別']).agg({'身高':['min'],'體重':['max']})
df.groupby('flee').agg({'身高': [np.median, np.mean], 'signs': np.mean})
df.agg({'A':np.sum,'B':np.mean})  # 對不同列進行不同的計算
df[['A','B']].agg([np.sum,np.mean,np.min])  # 對多個變數進行多種計算

# 時間分組 ,先用pd.to_datetime(欄位,格式)將某一列轉成日期格式
df.groupby(df['生日'].apply(lambda x:x.year)).count()
# 分組後選第一個,一般資料先排序
df.groupby(df['生日'].apply(lambda x:x.year),as_index=False).first()       # Tail(n=1) head()
# 找到每組中只有一個資料的
df.groupby(df['生日'].apply(lambda x:x.month),as_index=False).filter(lambda x: len(x)==1)
data2.groupby('var').filter(lambda x:len(x)>=10)
data.groupby(data.index.year)['年齡'].mean()

# 加權平均
final3_1 = data_jiep.groupby(['產業線','模號']).apply(lambda g: np.average(g['平均節拍'], weights=g['模次'])).reset_index()

# groupby作圖
data.groupby('race')['flee'].value_counts().unstack().plot(kind='bar', figsize=(20, 4))
data.groupby('flee')['age'].plot(kind='kde', legend=True, figsize=(20, 5))

# groupby中的幾個函數
# 累計  
df.groupby('key').aggregate('min', np.median, max)
# 過濾   
df.groupby('key').filter(某個函數)
# 轉換    
df.groupby('key').transform(lambda x: x- x.mean())

#通過某一個欄位分組後,選另一個欄位的最小值,構成的資料
df = pd.DataFrame({'AAA': [1, 1, 1, 2, 2, 2, 3, 3],'BBB': [2, 1, 3, 4, 5, 1, 2, 3]})
df.loc[df.groupby("AAA")["BBB"].idxmin()]
# 按照一個欄位排序,另一個欄位分組,選取第一個
df.sort_values(by="BBB").groupby("AAA", as_index=False).first()  #重新設定索引

# transform後資料大小不變
df["Order_Total"] = df.groupby('order')["ext price"].transform('sum')

result0 = data1.to_period('Q').groupby(level=0).apply(lambda x :len(x['var'].unique().tolist()))
  • 39 交叉表
result1 = pd.crosstab(data.index,data['產業線'],margins=True)
  • 40  資料透視表
df.pivot_table('價格',index='產地',columns='類別',aggfunc='max',margins=True,fill_value=0,margins_name='合計')

# 用字典形式,可不用values引數
df.pivot_table(index='sex', columns='class', aggfunc={'surviced':'sum', 'fare':'mean'})

result  = data.pivot_table(index=data3.to_period('M').index,columns= '是否異常',values='模號', aggfunc='count')

result1 = data.pivot_table(index= 'var1',columns=data['var3'].apply(lambda x: x.strftime('%Y')),
                      aggfunc='count',values='var2')
  • 41 視窗函數
#索引需要為日期 對於明細資料,計算固定大小區域的指標
s = pd.Series(np.random.randn(1000),index=pd.date_range('1/1/2000', periods=1000))
s = s.cumsum()
r = s.rolling(window=60)   
# window:移動視窗的大小
# min_periods:需要的非空資料點的閾值(否則結果為NA)
# center:布林值,是否將標籤設定在中間(預設為False)

df['數量_re'] = df['數量'].rolling('7D').sum()

data1 = data.set_index('入庫日期').groupby('供應商')['入庫量'].rolling('7D').sum().reset_index()
  • 42 標準化
# 當越小越好時
df['var_nor'] = (df['var'].max() - df['var']) / (df['var'].max() - df['var'].min())
# 當越大越好時
df['var_nor'] = (df['var'] - df['var'].min()) / (df['var'].max() - df['var'].min())
# 當中值為好是
df['var'] = np.abs(df['var']-標準值)
df['var_nor'] = (df['var'].max() - df['var']) / (df['var'].max() - df['var'].min())

# 可以寫成通用函數
def f2(data,col):
    col_name = col + '_nor'
    data_gp = data.groupby('類別').mean()
    data_gp[col_name] = (data_gp[col] - data_gp[col].min() ) / (data_gp[col].max() - data_gp[col].min() )
    return data_gp
  • 43  去掉異常值
def f2(data,col):
    q1 = data[col].quantile(q=0.25)     
    q3 = data[col].quantile(q=0.75)
    iqr = q3 - q1
    t1 = q1 - 3*iqr
    t2 = q3 + 3*iqr
    return data[(data[col]>t1)&(data[col]<t2)][['類別',col]]
  • 44 正太分佈和指數分佈資料
data_norm = pd.DataFrame({'正太分佈':np.random.normal(loc=60,scale=15,size=10000)})
data_exp = pd.DataFrame({'指數分佈':np.random.exponential(scale=15,size=10000)+45})
  • 45 隨機選擇
df['strategy'] = np.random.choice([1,2,3],99)
  • 46 行列求和
# 增加列合計
df['合計']  = df.sum(axis=1)
# 增加行合計
df.loc['合計']  = df.sum(axis=0)
  • 47 資料平移
data['經度_前1天'] = data.groupby('var')['經度'].shift(1)
  • 48 寬錶轉窄表
test = pd.DataFrame(fake_data, columns=['subject', 'A', 'B', 'C'])
test
    subject    A    B    C
0    math      88   70   60
1    english   90   80   78

# 轉換為窄表
pd.melt(test, id_vars=['subject'])
data3 = pd.melt(data2, id_vars=['var1','var2'])
     subject    variable    value
0    math       A           88
1    english    A           90
2    math       B           70
3    english    B           80
4    math       C           60
5    english    C           78
  • 49 二維表
df.to_numpy()
  • 50 改字典列表
df.set_index('ID').T.to_dict('list')
{'p': [1, 3, 2], 'q': [4, 3, 2], 'r': [4, 0, 9]}
  • 51 轉字典列表
datajs = data.to_json(orient='records',force_ascii=False)
# 名稱,經度,維度,數值
[{"name":"虹橋火車站","lng":121.327908,"lat":31.20033,"value":3.5225437574},{"name":"上海火車站","lng":121.46396,"lat":31.255155,"value":7.0937954904}]
  • 52 兩列較大值
df['z']=df[['x','y']].max(axis=1)

以上內容為日常工作中總結, 實用性強, 大家可結合自己工作再重新整理, 儲存到電腦上隨時取用, 順便說下本人(非計算機專業)學習python的一些經驗:

  1. 找一本基礎書: 有時間就看, 沒有時間碰到問題時當參考書用. 比如《利用python進行資料分析》或者《python資料科學手冊》;
  2. 做電子筆記: 書中的功能太多, 而工作常用的並不多, 平時使用或者發現好的用法分類整理成電子筆記. 隨用隨取;
  3. 找關聯: 將所學內容和工作中的要處理的事情關聯;
  4. 在平臺多看一些大牛們整理的資料, 找對自己有用的轉換成自己的;

如果對你有幫助, 別忘了關注、點贊喲!

快速掌握以上技巧課程推薦: 連結請點選→