數據分析(3)--Pandas數據處理

一、概述

前面我們學習了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)

結果:

image.png

補充學習

# 可以對兩列進行分組
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的值。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末毡证,一起剝皮案震驚了整個濱河市电爹,隨后出現的幾起案子,更是在濱河造成了極大的恐慌情竹,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異秦效,居然都是意外死亡雏蛮,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門阱州,熙熙樓的掌柜王于貴愁眉苦臉地迎上來挑秉,“玉大人,你說我怎么就攤上這事苔货∠牛” “怎么了?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵夜惭,是天一觀的道長姻灶。 經常有香客問我,道長诈茧,這世上最難降的妖魔是什么产喉? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮敢会,結果婚禮上曾沈,老公的妹妹穿的比我還像新娘。我一直安慰自己鸥昏,他們只是感情好塞俱,可當我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著吏垮,像睡著了一般障涯。 火紅的嫁衣襯著肌膚如雪缩宜。 梳的紋絲不亂的頭發(fā)上苦蒿,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天安疗,我揣著相機與錄音智什,去河邊找鬼吐葱。 笑死缰趋,一個胖子當著我的面吹牛寺鸥,可吹牛的內容都是我干的蛤虐。 我是一名探鬼主播媳谁,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼涂滴,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了晴音?” 一聲冷哼從身側響起柔纵,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎锤躁,沒想到半個月后搁料,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年郭计,在試婚紗的時候發(fā)現自己被綠了霸琴。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡昭伸,死狀恐怖梧乘,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情庐杨,我是刑警寧澤选调,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站灵份,受9級特大地震影響仁堪,放射性物質發(fā)生泄漏。R本人自食惡果不足惜各吨,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一枝笨、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧揭蜒,春花似錦横浑、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至瑰谜,卻和暖如春欺冀,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背萨脑。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工隐轩, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人渤早。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓职车,卻偏偏與公主長得像,于是被迫代替她去往敵國和親鹊杖。 傳聞我的和親對象是個殘疾皇子悴灵,可洞房花燭夜當晚...
    茶點故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內容