一、概述
前面我們學習了pandas一些基本的知識拥诡,這一篇文章我們來學習pandas的數據處理触趴,一些數學運算氮发、排序、合并冗懦、apply數據預處理爽冕、去重、時間序列操作披蕉、分組颈畸,聚合、透視表等知識没讲。
二眯娱、簡單計算
首先我們先導入需要的模塊:
import numpy as np
import pandas as pd
from pandas import Series, DataFrame
實例:
#Series 計算 可以計算加減乘,這里以加法為例
s1 = Series([1,2,3], index=['B','C','D'])
s2 = Series([4,5,6,7], index=['B','C','D','E'])
# 沒有的數據為nan,對應的index相加
print(s1 + s2)
# DataFrame計算爬凑,可加減乘,以加法為例
df1 = DataFrame(np.arange(4).reshape(2,2), index=['A','B'], columns=['BJ','GZ'])
df2 = DataFrame(np.arange(9).reshape(3,3), index=['A','B','C'], columns=['BJ', 'GZ', 'SH'])
print(df1 + df2)#沒有數據的NaN,對應的index做運算
結果:
-
DataFrame相關函數
DataFrame常用函數:sum()
徙缴、max()
、min()
嘁信、describe()
等
實例:
df3 = DataFrame([[1,2,3],[4,5,np.nan],[7,8,9]], index=['A','B','C'], columns=['c1','c2','c3'])
print(df3,'原始數據')
# 列和
print(df3.sum(),'列的和')
# 行和
print(df3.sum(axis=1),'行的和')
# 最大值與最小值
print(df3.max(),'列最大值')
print(df3.max(axis=1),'行最大值')
print(df3.min(),'列最小值')
print(df3.min(axis=1),'行最小值')
# describe描述
df3.describe()
結果:
總結:
axis
參數默認等于0于样,求得是列的值,當axis=1時求得是行的值吱抚,describbe()
返回的是具體一個統(tǒng)計的結果的表格百宇。
三、Series和DataFrame排序
- 排序方式兩種秘豹,一種是按values,一種是按index
Series實例:
s1 = Series(np.random.randn(5))
print('原始順序',s1)
# 值排序
s2 = s1.sort_values()
print('按值升序排序',s2)
s2 = s1.sort_values(ascending=False)
print('# 按值降序排序 ',s2)
# 對index進行排序,降序同樣修改ascending為False就好
print('按index升序排序',s2.sort_index())
print('按index降序排序',s2.sort_index())
結果:
DataFrame實例:
# DataFrame排序
df1 = DataFrame(np.random.randn(20).reshape(4,5), columns=['A','B','C','D','E'])
print(df1)
print("***************")
# 某一列Series升序排序
print(df1['A'].sort_values())
print("***************")
# DataFrame對某列進行排序
print(df1.sort_values('A'))
# 降序排序
print(df1.sort_values('A', ascending=False))
print("***************")
df2=df1.sort_values('A', ascending=False)
# 對index進行排序
df2.sort_index()
結果:
四携御、DataFrame重命名
實例:
df1 = DataFrame(np.arange(9).reshape(3,3), index=['BJ','SH','GZ'], columns=['A','B','C'])
print(df1)
print(df1.index)
print("***************")
# 方式一,直接用Series修改
df1.index = ['SZ','HZ','CQ']
print(df1.index)
print("***************")
# 方式二既绕,使用map進行修改
print(df1.index.map(str.lower))
print("***************")
# 方式三啄刹,使用rename進行修改
print(df1.rename(index=str.upper))
print("***************")
# 同時修改行和列
df1 = df1.rename(index=str.lower, columns=str.lower)
print(df1)
print("***************")
df1.rename(index={'sz':'shenzen'}, columns={'a':'A'})
結果:
五、DataFrame的merge(合并)
-
merge()
函數常用參數有on
默認是NoNe
,on為指定列凄贩,默認情況下會自動找到相同名列,若指定了不同名列會保錯誓军,有兩列以上相同的需要指定on;
how是指連接的方式,how=inner(默認),left,right,outer
實例:
df1 = DataFrame({'key':['X','Y','Z'], 'data_set1':[1,2,3]})
df2 = DataFrame({'key':['A','B','C'], 'data_set2':[4,5,6]})
# 沒有相同的列值
print(pd.merge(df1,df2))
print("***************")
# 默認合并
df2 = DataFrame({'key':['X','B','C'], 'data_set_2':[4,5,6]})
print(pd.merge(df1,df2))
print("***************")
df1 = DataFrame({'key':['X','Y','Z','X'], 'data_set_1':[1,2,3,4]})
print(pd.merge(df1,df2))
print("***************")
# on為指定列,默認情況下會自動找到相同名列,若指定了不同名列會保錯疲扎,有兩列以上相同的需要指定on
print(pd.merge(df1,df2,on='key'))
print("*********************************************************")
# 連接的方式,how=inner(默認),left,right,outer
print(pd.merge(df1,df2,on='key',how='inner'))
print("***************")
print(pd.merge(df1,df2,on='key',how='left'))
print("***************")
print(pd.merge(df1,df2,on='key',how='right'))
print("***************")
print(pd.merge(df1,df2,on='key',how='outer'))
結果:
六昵时、Concatenate和Combine
- Concatenate
# arrange上的Concatenate
arr1 = np.arange(9).reshape(3,3)
arr2 = np.arange(9).reshape(3,3)
# 進行concatenate,axis參數表示結合方向,默認0是縱向結合
print(np.concatenate([arr1,arr2]))#縱向
print("***************")
print(np.concatenate([arr1,arr2], axis=1))#橫向
print("******************************************")
# Series上的concatenate
s1 = Series([1,2,3], index=['X','Y','Z'])
S2 = Series([4,5], index=['A','B'])
print(pd.concat([s1,S2]))#縱向
print("***************")
# 缺失值會補齊為NaN
print(pd.concat([s1,S2], axis=1))#橫向
print("******************************************")
df1 = DataFrame(np.random.rand(3,3), columns=['X','Y','Z'])
df2 = DataFrame(np.random.rand(2,3), columns=['X','Y','A'])
print(pd.concat([df1,df2]))
print("***************")
print(pd.concat([df1,df2],axis=1))
結果:
- Combine
實例:
# Combine,后一個對象補齊前一個對象
# Series
s1 = Series([2,np.nan,4,np.nan], index=['A','B','C','D'])
print(s1)
print("***************")
s2 = Series([1,2,3,4], index=['A','B','C','D'])
print(s2)
print("***************")
print(s1.combine_first(s2))
print("******************************************")
df1 = DataFrame({'X':[1,np.nan,3,np.nan], 'Y':[5,np.nan,7,np.nan], 'Z':[9,np.nan,11,np.nan]})
print(df1)
print("***************")
df2 = DataFrame({'Z':[np.nan,10,np.nan,12], 'A':[1,2,3,4]})
print(df2)
print("***************")
print(df1.combine_first(df2))
結果:
七椒丧、通過apply對數據進行處理
- 首先我們讀取需要的數據:
f = open('apply_demo.csv')
df = pd.read_csv(f)
df.head()
結果:
實例:
# apply傳如一個函數,對某一列進行處理
# 通過分析壹甥,我們需要的是如下數據
# 定義一個處理函數
def foo(line):
items = line.strip().split(' ')
return Series([items[1], items[3], items[5]])
# 使用apply處理data列
df_temp = df['data'].apply(foo)
df_temp.head()
結果:
實例:
# 修改列名
df_temp = df_temp.rename(columns = {0:'Symbol', 1:'Seqno', 2:'Price'})
# 添加到原df中
df_new = df.combine_first(df_temp)
# 刪除掉無關列并生成csv
del df_new['data'], df_new[ 'A']
#寫入文件
df_new.to_csv('demo_duplicate.csv')
結果:
七、Series和DataFrame去重
- 首先讀取數據結果:
實例:
df.size#查看元素數量
Out[41]: 19945
len(df)#查看數據長度
Out[42]: 3989
len(df['Seqno'].unique())#查看某列去重后的數據長度
Out[46]: 1000
# DataFrame去重壶熏,drop_dupliates
df.drop_duplicates(['Seqno'], keep='last').head()
#keep參數指定保留哪一個,默認first保留第一個句柠,last保留最后一個
結果:
八、時間序列操作
- 首先在原有模塊的基礎上導入時間模塊:
from datetime import datetime
*時間序列的生成
實例:
# 方式一、生成一個時間
t1 = datetime(2009, 10, 20)
print(t1)
print("***************")
#手寫一個時間列表
date_list = [datetime(2016,9,1), datetime(2016,9,10), datetime(2017,9,1),datetime(2017,9,20)]
print(date_list)
print("***************")
# Series是index改為date_list
s1 = Series(np.random.rand(4), index=date_list)
print(s1)
print("***************")
# 最后查看下index 是一個DatetimeIndex
print(s1.index)
print("******************************************")
# 對Series訪問,有多種寫法
print(s1[datetime(2016,9,10)])
print("***************")
print(s1['2016-9-10'])
print("***************")
print(s1['20160910'])
print("***************")
# 不可以直接'201609',報錯
print(s1['2016-09'])
print("******************************************")
# 方式二溯职、pandas生成Datetime精盅,一個開始參數,一個結束參數谜酒,periods表示數量叹俏,freq表示間隔
# 生成21個,freq默認為'D'天數
date_list = pd.date_range('2016-01-01', periods=21)
print(date_list)
print("***************")
# 修改freq甚带,每周一
date_list = pd.date_range('2016-01-01', periods=21, freq='W-MON')
print(date_list)
print("***************")
# 間隔6小時
date_list = pd.date_range('2016-01-01','2016-02-01', freq='6H')
print(date_list)
print("***************")
# 最后設置Series的index
s2=Series(np.random.rand(28), index=date_list)
結果:
-
時間序列采樣
實例:
# 生成一個時間序列
t_range = pd.date_range('2016-01-01', '2016-12-31')
# 創(chuàng)建Series她肯,設置index
s1 = Series(np.random.randn(len(t_range)), index=t_range)
# 一月份取平均值
print(s1['2016-01'].mean())
print("***************")
# 對月份取平均值
s1_month = s1.resample('M').mean()
print(s1_month)
# 前填充ffill,比如一號里的沒有的數據是從1月1號采取過來的
print(s1.resample('H').ffill())
print("***************")
# 后填充bfill鹰贵,比如一號里的沒有的數據是從1月2號采取過來的
print(s1.resample('H').bfill())
結果:
-
時間序列畫圖
實例:
# 畫圖
# 新建一個時間序列
t_range = pd.date_range('2016-01-01', '2016-12-31')
# 建立一個DataFrame
stock_df = DataFrame(index=t_range)
# 加入兩行晴氨,模擬股票
stock_df['BABA'] = np.random.randint(80, 100, size=len(t_range))
stock_df['TENCENT'] = np.random.randint(30, 50, size=len(t_range))
# 顯示圖片,下面
stock_df.plot()
# 數據過于密集,重新清洗碉输,按周清洗
weekly_df = DataFrame()
# resample參數w表示周分類籽前,再取平均值
weekly_df['BABA'] = stock_df['BABA'].resample('W').mean()
weekly_df['TENCENT'] = stock_df['TENCENT'].resample('W').mean()
# 顯示
weekly_df.plot()
結果:
九、數據分箱(Binning) 分組(Groupby) 聚合(Aggregation)
- 數據分箱(Binning)
實例:
# 隨機生成一段成績
score_list = np.random.randint(25, 100, size=20)
print(score_list)
print("***************")
# 進行cut分箱敷钾, bins為剪切范圍
bins = [0,59,70,80,100]
print(pd.cut(score_list, bins))
print("***************")
# 查看數據枝哄,通過pd.value_counts()查看Categories數據
score_cat = pd.cut(score_list, bins)
print(pd.value_counts(score_cat))
print("***************")
# 模擬一段數據
df = DataFrame()
df['score'] = score_list
# 隨機生成3個字符pd.util.testing.rands(3)
df['student'] = [pd.util.testing.rands(3) for i in range(20)]
# 對score進行分箱
print(pd.cut(df['score'], bins))
print("***************")
# 傳入labels標簽,進行分箱標記
df['categories'] = pd.cut(df['score'], bins, labels=['low','ok','good','great'])
df
結果:
- 數據分組
groupby()
實例:
# 打開文件
f = open('city_weather.csv')
df = pd.read_csv(f)
df
數據效果:
實例通過城市分類:
g = df.groupby(df['city'])
g.groups
效果:
其他的分組處理實例:
# 獲取某一個組,以BJ為例
g.get_group('BJ')
# 對某一個組進行處理
df_bj = g.get_group('BJ')
df_bj.mean()#求BJ這一組的平均值
df_bj.describe()#返回一個詳細的統(tǒng)計結果
# 查看整個groupby
g.mean()
# groupby可轉換為列表阻荒,列表中為元組挠锥,元組中第一個值為分組名,第二個值為dataframe
list(g)
# 可以裝換為字典
dict(list(g))
- 數據聚合
agg()
先看數據展示效果:
實例:
# 對df進行分組
g = df.groupby('city')
# 實驗聚合函數min,求每個城市的最小值
g.agg('min')
# 自定義函數侨赡,目的查看傳如函數的數據類型
# 自定義函數進行聚合
def foo (attr):
return attr.max() - attr.min()
#傳入一個Sreies對象
g.agg(foo)
結果:
補充學習
# 可以對兩列進行分組
g_new = df.groupby(['city', 'wind'])
g_new.groups
# 獲取某一組
g_new.get_group(('BJ',2)
十蓖租、數據透視表
實例:
# 打開excel文件
xlsx = pd.ExcelFile('sales-funnel.xlsx')
df = pd.read_excel(xlsx)
# 生成透視表
# aggfunc默認取平均值
pd.pivot_table(df,index=['Name'])
實例操作:
# 可以設置多個index,多級
pd.pivot_table(df, index=['Name','Rep','Manager'])
# 多級index羊壹,經理和銷售顧問
pd.pivot_table(df, index=['Manager','Rep'])
# 可以指定生成那個values
pd.pivot_table(df, index=['Manager','Rep'], values=['Price'])
# 可多個values蓖宦,修改聚合函數
pd.pivot_table(df, index=['Manager','Rep'], values=['Price','Quantity'], aggfunc='sum')
# 可以添加colunms,多級columns
pd.pivot_table(df, index=['Manager','Rep'], values=['Price','Quantity'], columns=['Product'],aggfunc='sum')
# 對沒有的數據賦值
df_pivot = pd.pivot_table(df, index=['Manager','Rep'], values=['Price','Quantity'], columns=['Product'],fill_value=0,aggfunc='sum')
- 總結:
pivot_table()
有多個參數油猫,data
表示需要透視的數據稠茂,index
表示需要透視的columns
,順序不同效果不同,aggfunc
表示聚合的函數情妖,values
表示顯示的值睬关,fill_values
可以設置NAN的值。