人工智慧-機器學習-Python-第三方庫-Pandas(用於資料處理)

ninjawei發表於2020-11-17

一、Pandas介紹

學習目標

  • 目標
    • 瞭解什麼是pandas
    • 瞭解Numpy與Pandas的不同
    • 知道使用pandas的優勢

1 Pandas介紹

在這裡插入圖片描述

  • 2008年WesMcKinney開發出的庫
  • 專門用於資料探勘的開源python庫
  • 以Numpy為基礎,借力Numpy模組在計算方面效能高的優勢
  • 基於matplotlib,能夠簡便的畫圖
  • 獨特的資料結構

2 為什麼使用Pandas

Numpy已經能夠幫助我們處理資料,能夠結合matplotlib解決部分資料展示等問題,那麼pandas學習的目的在什麼地方呢?

  • 增強圖表可讀性

    • 回憶我們在numpy當中建立學生成績表樣式:

    • 返回結果:

      array([[92, 55, 78, 50, 50],
             [71, 76, 50, 48, 96],
             [45, 84, 78, 51, 68],
             [81, 91, 56, 54, 76],
             [86, 66, 77, 67, 95],
             [46, 86, 56, 61, 99],
             [46, 95, 44, 46, 56],
             [80, 50, 45, 65, 57],
             [41, 93, 90, 41, 97],
             [65, 83, 57, 57, 40]])
      

      如果資料展示為這樣,可讀性就會更友好:

    在這裡插入圖片描述

  • 便捷的資料處理能力

    在這裡插入圖片描述

  • 讀取檔案方便
  • 封裝了Matplotlib、Numpy的畫圖和計算

3 小結

  • pandas的優勢【瞭解】
    • 增強圖表可讀性
    • 便捷的資料處理能力
    • 讀取檔案方便
    • 封裝了Matplotlib、Numpy的畫圖和計算



二、Pandas資料結構

學習目標

  • 目標
    • 知道Pandas的Series結構
    • 掌握Pandas的Dataframe結構
    • 瞭解Pandas的MultiIndex與panel結構

Pandas中一共有三種資料結構,分別為:Series、DataFrame和MultiIndex(老版本中叫Panel )。

其中Series是一維資料結構,DataFrame是二維的表格型資料結構,MultiIndex是三維的資料結構。

1.Series

Series是一個類似於一維陣列的資料結構,它能夠儲存任何型別的資料,比如整數、字串、浮點數等,主要由一組資料和與之相關的索引兩部分構成。

在這裡插入圖片描述

1.1 Series的建立

# 匯入pandas
import pandas as pd

pd.Series(data=None, index=None, dtype=None)
  • 引數:
    • data:傳入的資料,可以是ndarray、list等
    • index:索引,必須是唯一的,且與資料的長度相等。如果沒有傳入索引引數,則預設會自動建立一個從0-N的整數索引。
    • dtype:資料的型別

通過已有資料建立

  • 指定內容,預設索引
pd.Series(np.arange(10))
# 執行結果
0    0
1    1
2    2
3    3
4    4
5    5
6    6
7    7
8    8
9    9
dtype: int64
  • 指定索引
pd.Series([6.7,5.6,3,10,2], index=[1,2,3,4,5])
# 執行結果
1     6.7
2     5.6
3     3.0
4    10.0
5     2.0
dtype: float64
  • 通過字典資料建立
color_count = pd.Series({'red':100, 'blue':200, 'green': 500, 'yellow':1000})
color_count
# 執行結果
blue       200
green      500
red        100
yellow    1000
dtype: int64

1.2 Series的屬性

為了更方便地操作Series物件中的索引和資料,Series中提供了兩個屬性index和values

  • index
color_count.index

# 結果
Index(['blue', 'green', 'red', 'yellow'], dtype='object')
  • values
color_count.values

# 結果
array([ 200,  500,  100, 1000])

也可以使用索引來獲取資料:

color_count[2]

# 結果
100

2.DataFrame

DataFrame是一個類似於二維陣列或表格(如excel)的物件,既有行索引,又有列索引

  • 行索引,表明不同行,橫向索引,叫index,0軸,axis=0
  • 列索引,表名不同列,縱向索引,叫columns,1軸,axis=1

在這裡插入圖片描述

2.1 DataFrame的建立

# 匯入pandas
import pandas as pd

pd.DataFrame(data=None, index=None, columns=None)
  • 引數:

    • index:行標籤。如果沒有傳入索引引數,則預設會自動建立一個從0-N的整數索引。
    • columns:列標籤。如果沒有傳入索引引數,則預設會自動建立一個從0-N的整數索引。
  • 通過已有資料建立

舉例一:

pd.DataFrame(np.random.randn(2,3))

在這裡插入圖片描述

回憶我們們在前面直接使用np建立的陣列顯示方式,比較兩者的區別。

舉例二:建立學生成績表

# 生成10名同學,5門功課的資料
score = np.random.randint(40, 100, (10, 5))

# 結果
array([[92, 55, 78, 50, 50],
       [71, 76, 50, 48, 96],
       [45, 84, 78, 51, 68],
       [81, 91, 56, 54, 76],
       [86, 66, 77, 67, 95],
       [46, 86, 56, 61, 99],
       [46, 95, 44, 46, 56],
       [80, 50, 45, 65, 57],
       [41, 93, 90, 41, 97],
       [65, 83, 57, 57, 40]])

但是這樣的資料形式很難看到儲存的是什麼的樣的資料,可讀性比較差!!

問題:如何讓資料更有意義的顯示

# 使用Pandas中的資料結構
score_df = pd.DataFrame(score)

在這裡插入圖片描述

給分數資料增加行列索引,顯示效果更佳

效果:

在這裡插入圖片描述

  • 增加行、列索引
# 構造行索引序列
subjects = ["語文", "數學", "英語", "政治", "體育"]

# 構造列索引序列
stu = ['同學' + str(i) for i in range(score_df.shape[0])]

# 新增行索引
data = pd.DataFrame(score, columns=subjects, index=stu)

2.2 DataFrame的屬性

  • shape
data.shape

# 結果
(10, 5)
  • index

DataFrame的行索引列表

data.index

# 結果
Index(['同學0', '同學1', '同學2', '同學3', '同學4', '同學5', '同學6', '同學7', '同學8', '同學9'], dtype='object')
  • columns

DataFrame的列索引列表

data.columns

# 結果
Index(['語文', '數學', '英語', '政治', '體育'], dtype='object')
  • values

直接獲取其中array的值

data.values

array([[92, 55, 78, 50, 50],
       [71, 76, 50, 48, 96],
       [45, 84, 78, 51, 68],
       [81, 91, 56, 54, 76],
       [86, 66, 77, 67, 95],
       [46, 86, 56, 61, 99],
       [46, 95, 44, 46, 56],
       [80, 50, 45, 65, 57],
       [41, 93, 90, 41, 97],
       [65, 83, 57, 57, 40]])
  • T

轉置

data.T

結果

在這裡插入圖片描述

  • head(5):顯示前5行內容

如果不補充引數,預設5行。填入引數N則顯示前N行

data.head(5)

在這裡插入圖片描述

  • tail(5):顯示後5行內容

如果不補充引數,預設5行。填入引數N則顯示後N行

data.tail(5)

2.3 DatatFrame索引的設定

需求:

在這裡插入圖片描述

2.3.1 修改行列索引值

stu = ["學生_" + str(i) for i in range(score_df.shape[0])]

# 必須整體全部修改
data.index = stu

注意:以下修改方式是錯誤的

# 錯誤修改方式
data.index[3] = '學生_3'

2.3.2 重設索引

  • reset_index(drop=False)
    • 設定新的下標索引
    • drop:預設為False,不刪除原來索引,如果為True,刪除原來的索引值
# 重置索引,drop=False
data.reset_index()

在這裡插入圖片描述

# 重置索引,drop=True
data.reset_index(drop=True)

2.3.3 以某列值設定為新的索引

  • set_index(keys, drop=True)
    • keys : 列索引名成或者列索引名稱的列表
    • drop : boolean, default True.當做新的索引,刪除原來的列

設定新索引案例

1、建立

df = pd.DataFrame({'month': [1, 4, 7, 10],
                    'year': [2012, 2014, 2013, 2014],
                    'sale':[55, 40, 84, 31]})

   month  sale  year
0  1      55    2012
1  4      40    2014
2  7      84    2013
3  10     31    2014

2、以月份設定新的索引

df.set_index('month')
       sale  year
month
1      55    2012
4      40    2014
7      84    2013
10     31    2014

3、設定多個索引,以年和月份

df = df.set_index(['year', 'month'])
df
            sale
year  month
2012  1     55
2014  4     40
2013  7     84
2014  10    31

注:通過剛才的設定,這樣DataFrame就變成了一個具有MultiIndex的DataFrame。

3.MultiIndex與Panel

3.1 MultiIndex

MultiIndex是三維的資料結構;

多級索引(也稱層次化索引)是pandas的重要功能,可以在Series、DataFrame物件上擁有2個以及2個以上的索引。

3.1.1 multiIndex的特性

列印剛才的df的行索引結果

df.index

MultiIndex(levels=[[2012, 2013, 2014], [1, 4, 7, 10]],
           labels=[[0, 2, 1, 2], [0, 1, 2, 3]],
           names=['year', 'month'])

多級或分層索引物件。

  • index屬性
    • names:levels的名稱
    • levels:每個level的元組值
df.index.names
# FrozenList(['year', 'month'])

df.index.levels
# FrozenList([[1, 2], [1, 4, 7, 10]])

3.1.2 multiIndex的建立

arrays = [[1, 1, 2, 2], ['red', 'blue', 'red', 'blue']]
pd.MultiIndex.from_arrays(arrays, names=('number', 'color'))

# 結果
MultiIndex(levels=[[1, 2], ['blue', 'red']],
           codes=[[0, 0, 1, 1], [1, 0, 1, 0]],
           names=['number', 'color'])

3.2 Panel

3.2.1 panel的建立

  • class pandas.Panel(data=None, items=None, major_axis=None, minor_axis=None)

    • 作用:儲存3維陣列的Panel結構

    • 引數:

      • data : ndarray或者dataframe

      • items : 索引或類似陣列的物件,axis=0

      • major_axis : 索引或類似陣列的物件,axis=1

      • minor_axis : 索引或類似陣列的物件,axis=2

p = pd.Panel(data=np.arange(24).reshape(4,3,2),
                 items=list('ABCD'),
                 major_axis=pd.date_range('20130101', periods=3),
                 minor_axis=['first', 'second'])

# 結果
<class 'pandas.core.panel.Panel'>
Dimensions: 4 (items) x 3 (major_axis) x 2 (minor_axis)
Items axis: A to D
Major_axis axis: 2013-01-01 00:00:00 to 2013-01-03 00:00:00
Minor_axis axis: first to second

3.2.2 檢視panel資料

p[:,:,"first"]
p["B",:,:]

注:Pandas從版本0.20.0開始棄用:推薦的用於表示3D資料的方法是通過DataFrame上的MultiIndex方法

4 小結

  • pandas的優勢【瞭解】
    • 增強圖表可讀性
    • 便捷的資料處理能力
    • 讀取檔案方便
    • 封裝了Matplotlib、Numpy的畫圖和計算
  • series【知道】
    • 建立
      • pd.Series([], index=[])
      • pd.Series({})
    • 屬性
      • 物件.index
      • 物件.values
  • DataFrame【掌握】
    • 建立
      • pd.DataFrame(data=None, index=None, columns=None)
    • 屬性
      • shape – 形狀
      • index – 行索引
      • columns – 列索引
      • values – 檢視值
      • T – 轉置
      • head() – 檢視頭部內容
      • tail() – 檢視尾部內容
    • DataFrame索引
      • 修改的時候,需要進行全域性修改
      • 物件.reset_index()
      • 物件.set_index(keys)
  • MultiIndex與Panel【瞭解】
    • multiIndex:
      • 類似ndarray中的三維陣列
      • 建立:
        • pd.MultiIndex.from_arrays()
      • 屬性:
        • 物件.index
    • panel:
      • pd.Panel(data, items, major_axis, minor_axis)
      • panel資料要是想看到,則需要進行索引到dataframe或者series才可以



三、Pandas基本資料操作

學習目標

  • 目標
    • 記憶DataFrame的形狀、行列索引名稱獲取等基本屬性
    • 應用Series和DataFrame的索引進行切片獲取
    • 應用sort_index和sort_values實現索引和值的排序

為了更好的理解這些基本操作,我們將讀取一個真實的股票資料。關於檔案操作,後面在介紹,這裡只先用一下API

# 讀取檔案
data = pd.read_csv("./data/stock_day.csv")

# 刪除一些列,讓資料更簡單些,再去做後面的操作
data = data.drop(["ma5","ma10","ma20","v_ma5","v_ma10","v_ma20"], axis=1)

在這裡插入圖片描述

1 索引操作

Numpy當中我們已經講過使用索引選取序列和切片選擇,pandas也支援類似的操作,也可以直接使用列名、行名

稱,甚至組合使用。

1.1 直接使用行列索引(先列後行,直接索引時只能通過索引名進行索引,不能通過下標)

獲取’2018-02-27’這天的’close’的結果

# 直接使用行列索引名字的方式(先列後行)
data['open']['2018-02-27']
23.53

# 不支援的操作
# 錯誤
data['2018-02-27']['open']
# 錯誤
data[:1, :2]

1.2 結合loc或者iloc使用索引

獲取從’2018-02-27’:‘2018-02-22’,'open’的結果

# 使用loc:只能指定行列索引的名字(通過索引值索引;先行後列)
data.loc['2018-02-27':'2018-02-22', 'open']

2018-02-27    23.53
2018-02-26    22.80
2018-02-23    22.88
Name: open, dtype: float64

# 使用iloc可以通過索引的下標去獲取(通過索引下標索引;先行後列)
# 獲取前3天資料,前5列的結果
data.iloc[:3, :5]

	        open	high	close	low
2018-02-27	23.53	25.88	24.16	23.53
2018-02-26	22.80	23.78	23.53	22.80
2018-02-23	22.88	23.37	22.82	22.71

1.3 使用ix組合索引

Warning:Starting in 0.20.0, the .ix indexer is deprecated, in favor of the more strict .iloc and .loc indexers.

獲取行第1天到第4天,[‘open’, ‘close’, ‘high’, ‘low’]這個四個指標的結果

# 使用ix進行下表和名稱組合做引
data.ix[0:4, ['open', 'close', 'high', 'low']]

# 推薦使用loc和iloc來獲取的方式
data.loc[data.index[0:4], ['open', 'close', 'high', 'low']]
data.iloc[0:4, data.columns.get_indexer(['open', 'close', 'high', 'low'])]

	        open	close	high	low
2018-02-27	23.53	24.16	25.88	23.53
2018-02-26	22.80	23.53	23.78	22.80
2018-02-23	22.88	22.82	23.37	22.71
2018-02-22	22.25	22.28	22.76	22.02

2 賦值操作

對DataFrame當中的close列進行重新賦值為1

# 直接修改原來的值
data['close'] = 1
# 或者
data.close = 1

3 排序

排序有兩種形式,一種對於索引進行排序,一種對於內容進行排序

3.1 DataFrame排序

  • 使用df.sort_values(by=, ascending=)
    • 單個鍵或者多個鍵進行排序,
    • 引數:
      • by:指定排序參考的鍵
      • ascending:預設升序
        • ascending=False:降序
        • ascending=True:升序
# 按照開盤價大小進行排序 , 使用ascending指定按照大小排序
data.sort_values(by="open", ascending=True).head()

在這裡插入圖片描述

# 按照多個鍵進行排序
data.sort_values(by=['open', 'high'])

在這裡插入圖片描述

  • 使用df.sort_index給索引進行排序

這個股票的日期索引原來是從大到小,現在重新排序,從小到大

# 對索引進行排序
data.sort_index()

在這裡插入圖片描述

3.2 Series排序

  • 使用series.sort_values(ascending=True)進行排序

series排序時,只有一列,不需要引數

data['p_change'].sort_values(ascending=True).head()

2015-09-01   -10.03
2015-09-14   -10.02
2016-01-11   -10.02
2015-07-15   -10.02
2015-08-26   -10.01
Name: p_change, dtype: float64
  • 使用series.sort_index()進行排序

與df一致

# 對索引進行排序
data['p_change'].sort_index().head()

2015-03-02    2.62
2015-03-03    1.44
2015-03-04    1.57
2015-03-05    2.02
2015-03-06    8.51
Name: p_change, dtype: float64

4 總結

  • 1.索引【掌握】
    • 直接索引 – 先列後行,是需要通過索引的字串進行獲取
    • loc – 先行後列,是需要通過索引的字串進行獲取
    • iloc – 先行後列,是通過下標進行索引
    • ix – 先行後列, 可以用上面兩種方法混合進行索引
  • 2.賦值【知道】
    • data[""] = **
    • data.** = **
  • 3.排序【知道】
    • dataframe
      • 物件.sort_values()
      • 物件.sort_index()
    • series
      • 物件.sort_values()
      • 物件.sort_index()



四、Pandas: DataFrame運算

學習目標

  • 目標
    • 應用add等實現資料間的加、減法運算
    • 應用邏輯運算子號實現資料的邏輯篩選
    • 應用isin, query實現資料的篩選
    • 使用describe完成綜合統計
    • 使用max, min, mean, std完成統計計算
    • 使用idxmin、idxmax完成最大值最小值的索引
    • 使用cumsum等實現累計分析
    • 應用apply函式實現資料的自定義處理

1 算術運算

  • add(other)

比如進行數學運算加上具體的一個數字

data['open'].add(1)
# data['open']+1  # 也能成功,但是一般不會這麼使用,後面再用.head()比較麻煩

2018-02-27    24.53
2018-02-26    23.80
2018-02-23    23.88
2018-02-22    23.25
2018-02-14    22.49
  • sub(other)’

2 邏輯運算

2.1 邏輯運算子號

  • 例如篩選data[“open”] > 23的日期資料
    • data[“open”] > 23返回邏輯結果
data["open"] > 23

2018-02-27     True
2018-02-26    False
2018-02-23    False
2018-02-22    False
2018-02-14    False
# 邏輯判斷的結果可以作為篩選的依據
data[data["open"] > 23].head()

在這裡插入圖片描述

  • 完成多個邏輯判斷,
data[(data["open"] > 23) & (data["open"] < 24)].head()

在這裡插入圖片描述

2.2 邏輯運算函式

  • query(expr)
    • expr:查詢字串

通過query使得剛才的過程更加方便簡單

data.query("open<24 & open>23").head()
  • isin(values)

例如判斷’open’是否為23.53和23.85

# 可以指定值進行一個判斷,從而進行篩選操作
data[data["open"].isin([23.53, 23.85])]

在這裡插入圖片描述

3 統計運算

3.1 describe

綜合分析: 能夠直接得出很多統計結果,count, mean, std, min, max

# 計算平均值、標準差、最大值、最小值
data.describe()

在這裡插入圖片描述)

3.2 統計函式

Numpy當中已經詳細介紹,在這裡我們演示min(最小值), max(最大值), mean(平均值), median(中位數), var(方差), std(標準差),mode(眾數)結果:

countNumber of non-NA observations
sumSum of values
meanMean of values
medianArithmetic median of values
minMinimum
maxMaximum
modeMode
absAbsolute Value
prodProduct of values
stdBessel-corrected sample standard deviation
varUnbiased variance
idxmaxcompute the index labels with the maximum
idxmincompute the index labels with the minimum

對於單個函式去進行統計的時候,座標軸還是按照預設列“columns” (axis=0, default),如果要對行“index” 需要指定(axis=1)

  • max()、min()
# 使用統計函式:0 代表“列”求結果, 1 代表“行”求統計結果
data.max(0)

open                   34.99
high                   36.35
close                  35.21
low                    34.01
volume             501915.41
price_change            3.03
p_change               10.03
turnover               12.56
my_price_change         3.41
dtype: float64
  • std()、var()
# 方差
data.var(0)

open               1.545255e+01
high               1.662665e+01
close              1.554572e+01
low                1.437902e+01
volume             5.458124e+09
price_change       8.072595e-01
p_change           1.664394e+01
turnover           4.323800e+00
my_price_change    6.409037e-01
dtype: float64
  
# 標準差
data.std(0)

open                   3.930973
high                   4.077578
close                  3.942806
low                    3.791968
volume             73879.119354
price_change           0.898476
p_change               4.079698
turnover               2.079375
my_price_change        0.800565
dtype: float64
  • median():中位數

中位數為將資料從小到大排列,在最中間的那個數為中位數。如果沒有中間數,取中間兩個數的平均值。

df = pd.DataFrame({'COL1' : [2,3,4,5,4,2],
                   'COL2' : [0,1,2,3,4,2]})
                   
df.median()

COL1    3.5
COL2    2.0
dtype: float64
  • idxmax()、idxmin()
# 求出最大值的位置
data.idxmax(axis=0)

open               2015-06-15
high               2015-06-10
close              2015-06-12
low                2015-06-12
volume             2017-10-26
price_change       2015-06-09
p_change           2015-08-28
turnover           2017-10-26
my_price_change    2015-07-10
dtype: object


# 求出最小值的位置
data.idxmin(axis=0)

open               2015-03-02
high               2015-03-02
close              2015-09-02
low                2015-03-02
volume             2016-07-06
price_change       2015-06-15
p_change           2015-09-01
turnover           2016-07-06
my_price_change    2015-06-15
dtype: object

3.3 累計統計函式

函式作用
cumsum計算前1/2/3/…/n個數的和
cummax計算前1/2/3/…/n個數的最大值
cummin計算前1/2/3/…/n個數的最小值
cumprod計算前1/2/3/…/n個數的積

那麼這些累計統計函式怎麼用?

在這裡插入圖片描述

以上這些函式可以對series和dataframe操作

這裡我們按照時間的從前往後來進行累計

  • 排序
# 排序之後,進行累計求和
data = data.sort_index()
  • 對p_change進行求和
stock_rise = data['p_change']
# plot方法整合了前面直方圖、條形圖、餅圖、折線圖
stock_rise.cumsum()

2015-03-02      2.62
2015-03-03      4.06
2015-03-04      5.63
2015-03-05      7.65
2015-03-06     16.16
2015-03-09     16.37
2015-03-10     18.75
2015-03-11     16.36
2015-03-12     15.03
2015-03-13     17.58
2015-03-16     20.34
2015-03-17     22.42
2015-03-18     23.28
2015-03-19     23.74
2015-03-20     23.48
2015-03-23     23.74

那麼如何讓這個連續求和的結果更好的顯示呢?

在這裡插入圖片描述

如果要使用plot函式,需要匯入matplotlib.

import matplotlib.pyplot as plt
# plot顯示圖形
stock_rise.cumsum().plot()
# 需要呼叫show,才能顯示出結果
plt.show()

關於plot,稍後會介紹API的選擇

4 自定義運算

  • apply(func, axis=0)
    • func:自定義函式
    • axis=0:預設是列,axis=1為行進行運算
  • 定義一個對列,最大值-最小值的函式
data[['open', 'close']].apply(lambda x: x.max() - x.min(), axis=0)

open     22.74
close    22.85
dtype: float64

5 小結

  • 算術運算【知道】
  • 邏輯運算【知道】
    • 1.邏輯運算子號
    • 2.邏輯運算函式
      • 物件.query()
      • 物件.isin()
  • 統計運算【知道】
    • 1.物件.describe()
    • 2.統計函式
    • 3.累積統計函式
  • 自定義運算【知道】
    • apply(func, axis=0)



五、Pandas畫圖

學習目標

  • 目標
    • 瞭解DataFrame的畫圖函式
    • 瞭解Series的畫圖函式

1 pandas.DataFrame.plot

  • DataFrame.plot(kind=‘line’)
  • kind : str,需要繪製圖形的種類
    • ‘line’ : line plot (default)
    • ‘bar’ : vertical bar plot
    • ‘barh’ : horizontal bar plot
      • 關於“barh”的解釋:
      • http://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.plot.barh.html
    • ‘hist’ : histogram
    • ‘pie’ : pie plot
    • ‘scatter’ : scatter plot

更多細節:https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.plot.html?highlight=plot#pandas.DataFrame.plot

2 pandas.Series.plot

更多細節:https://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.plot.html?highlight=plot#pandas.Series.plot




六、Pandas檔案讀取與儲存

學習目標

  • 目標
    • 瞭解Pandas的幾種檔案讀取儲存操作
    • 應用CSV方式、HDF方式和json方式實現檔案的讀取和儲存

我們的資料大部分存在於檔案當中,所以pandas會支援複雜的IO操作,pandas的API支援眾多的檔案格式,如CSV、SQL、XLS、JSON、HDF5。

注:最常用的HDF5和CSV檔案

在這裡插入圖片描述

1 CSV

1.1 read_csv

  • pandas.read_csv(filepath_or_buffer, sep =’,’, usecols )
    • filepath_or_buffer:檔案路徑
    • sep :分隔符,預設用","隔開
    • usecols:指定讀取的列名,列表形式
  • 舉例:讀取之前的股票的資料
# 讀取檔案,並且指定只獲取'open', 'close'指標
data = pd.read_csv("./data/stock_day.csv", usecols=['open', 'close'])

			open	close
2018-02-27	23.53	24.16
2018-02-26	22.80	23.53
2018-02-23	22.88	22.82
2018-02-22	22.25	22.28
2018-02-14	21.49	21.92

1.2 to_csv

  • DataFrame.to_csv(path_or_buf=None, sep=’, ’, columns=None, header=True, index=True, mode=‘w’, encoding=None)
    • path_or_buf :檔案路徑
    • sep :分隔符,預設用","隔開
    • columns :選擇需要的列索引
    • header :boolean or list of string, default True,是否寫進列索引值
    • index:是否寫進行索引
    • mode:‘w’:重寫, ‘a’ 追加
  • 舉例:儲存讀取出來的股票資料
    • 儲存’open’列的資料,然後讀取檢視結果
# 選取10行資料儲存,便於觀察資料
data[:10].to_csv("./data/test.csv", columns=['open'])
# 讀取,檢視結果
pd.read_csv("./data/test.csv")

     Unnamed: 0	open
0	2018-02-27	23.53
1	2018-02-26	22.80
2	2018-02-23	22.88
3	2018-02-22	22.25
4	2018-02-14	21.49
5	2018-02-13	21.40
6	2018-02-12	20.70
7	2018-02-09	21.20
8	2018-02-08	21.79
9	2018-02-07	22.69

會發現將索引存入到檔案當中,變成單獨的一列資料。如果需要刪除,可以指定index引數,刪除原來的檔案,重新儲存一次。

# index:儲存不會講索引值變成一列資料
data[:10].to_csv("./data/test.csv", columns=['open'], index=False)

2 HDF5

2.1 read_hdf與to_hdf

HDF5檔案的讀取和儲存需要指定一個鍵,值為要儲存的DataFrame

  • pandas.read_hdf(path_or_buf,key =None,** kwargs)

    從h5檔案當中讀取資料

    • path_or_buffer:檔案路徑
    • key:讀取的鍵
    • return:Theselected object
  • DataFrame.to_hdf(path_or_buf, key, **kwargs)

2.2 案例

  • 讀取檔案
day_close = pd.read_hdf("./data/day_close.h5")

如果讀取的時候出現以下錯誤

在這裡插入圖片描述

需要安裝安裝tables模組避免不能讀取HDF5檔案

pip install tables

在這裡插入圖片描述

  • 儲存檔案
day_close.to_hdf("./data/test.h5", key="day_close")

再次讀取的時候, 需要指定鍵的名字

new_close = pd.read_hdf("./data/test.h5", key="day_close")

注意:優先選擇使用HDF5檔案儲存

  • HDF5在儲存的時候支援壓縮,使用的方式是blosc,這個是速度最快的也是pandas預設支援的
  • 使用壓縮可以提磁碟利用率,節省空間
  • HDF5還是跨平臺的,可以輕鬆遷移到hadoop 上面

3 JSON

JSON是我們常用的一種資料交換格式,前面在前後端的互動經常用到,也會在儲存的時候選擇這種格式。所以我們需要知道Pandas如何進行讀取和儲存JSON格式。

3.1 read_json

  • pandas.read_json(path_or_buf=None, orient=None, typ=‘frame’, lines=False)
    • 將JSON格式準換成預設的Pandas DataFrame格式
    • orient : string,Indication of expected JSON string format.
      • ‘split’ : dict like {index -> [index], columns -> [columns], data -> [values]}
        • split 將索引總結到索引,列名到列名,資料到資料。將三部分都分開了
      • ’records’ : list like [{column -> value}, … , {column -> value}]
        • records 以columns:values的形式輸出
      • ‘index’ : dict like {index -> {column -> value}}
        • index 以index:{columns:values}...的形式輸出
      • ’columns’ : dict like {column -> {index -> value}},預設該格式
        • colums 以columns:{index:values}的形式輸出
      • ‘values’ : just the values array
        • values 直接輸出值
    • lines : boolean, default False
      • 按照每行讀取json物件
    • typ : default ‘frame’, 指定轉換成的物件型別series或者dataframe

3.2 read_josn 案例

  • 資料介紹

這裡使用一個新聞標題諷刺資料集,格式為json。is_sarcastic:1諷刺的,否則為0;headline:新聞報導的標題;article_link:連結到原始新聞文章。儲存格式為:

{"article_link": "https://www.huffingtonpost.com/entry/versace-black-code_us_5861fbefe4b0de3a08f600d5", "headline": "former versace store clerk sues over secret 'black code' for minority shoppers", "is_sarcastic": 0}
{"article_link": "https://www.huffingtonpost.com/entry/roseanne-revival-review_us_5ab3a497e4b054d118e04365", "headline": "the 'roseanne' revival catches up to our thorny political mood, for better and worse", "is_sarcastic": 0}
  • 讀取

orient指定儲存的json格式,lines指定按照行去變成一個樣本

json_read = pd.read_json("./data/Sarcasm_Headlines_Dataset.json", orient="records", lines=True)

結果為:

在這裡插入圖片描述

3.3 to_json

  • DataFrame.to_json(path_or_buf=None, orient=None, lines=False)
    • 將Pandas 物件儲存為json格式
    • path_or_buf=None:檔案地址
    • orient:儲存的json形式,{‘split’,’records’,’index’,’columns’,’values’}
    • lines:一個物件儲存為一行

3.4 案例

  • 儲存檔案
json_read.to_json("./data/test.json", orient='records')

結果

[{"article_link":"https:\/\/www.huffingtonpost.com\/entry\/versace-black-code_us_5861fbefe4b0de3a08f600d5","headline":"former versace store clerk sues over secret 'black code' for minority shoppers","is_sarcastic":0},{"article_link":"https:\/\/www.huffingtonpost.com\/entry\/roseanne-revival-review_us_5ab3a497e4b054d118e04365","headline":"the 'roseanne' revival catches up to our thorny political mood, for better and worse","is_sarcastic":0},{"article_link":"https:\/\/local.theonion.com\/mom-starting-to-fear-son-s-web-series-closest-thing-she-1819576697","headline":"mom starting to fear son's web series closest thing she will have to grandchild","is_sarcastic":1},{"article_link":"https:\/\/politics.theonion.com\/boehner-just-wants-wife-to-listen-not-come-up-with-alt-1819574302","headline":"boehner just wants wife to listen, not come up with alternative debt-reduction ideas","is_sarcastic":1},{"article_link":"https:\/\/www.huffingtonpost.com\/entry\/jk-rowling-wishes-snape-happy-birthday_us_569117c4e4b0cad15e64fdcb","headline":"j.k. rowling wishes snape happy birthday in the most magical way","is_sarcastic":0},{"article_link":"https:\/\/www.huffingtonpost.com\/entry\/advancing-the-worlds-women_b_6810038.html","headline":"advancing the world's women","is_sarcastic":0},....]
  • 修改lines引數為True
json_read.to_json("./data/test.json", orient='records', lines=True)

結果

{"article_link":"https:\/\/www.huffingtonpost.com\/entry\/versace-black-code_us_5861fbefe4b0de3a08f600d5","headline":"former versace store clerk sues over secret 'black code' for minority shoppers","is_sarcastic":0}
{"article_link":"https:\/\/www.huffingtonpost.com\/entry\/roseanne-revival-review_us_5ab3a497e4b054d118e04365","headline":"the 'roseanne' revival catches up to our thorny political mood, for better and worse","is_sarcastic":0}
{"article_link":"https:\/\/local.theonion.com\/mom-starting-to-fear-son-s-web-series-closest-thing-she-1819576697","headline":"mom starting to fear son's web series closest thing she will have to grandchild","is_sarcastic":1}
{"article_link":"https:\/\/politics.theonion.com\/boehner-just-wants-wife-to-listen-not-come-up-with-alt-1819574302","headline":"boehner just wants wife to listen, not come up with alternative debt-reduction ideas","is_sarcastic":1}
{"article_link":"https:\/\/www.huffingtonpost.com\/entry\/jk-rowling-wishes-snape-happy-birthday_us_569117c4e4b0cad15e64fdcb","headline":"j.k. rowling wishes snape happy birthday in the most magical way","is_sarcastic":0}...

4 小結

  • pandas的CSV、HDF5、JSON檔案的讀取【知道】
    • 物件.read_**()
    • 物件.to_**()



七、Pandas高階處理-缺失值處理

學習目標

  • 目標
    • 應用isnull判斷是否有缺失資料NaN
    • 應用fillna實現缺失值的填充
    • 應用dropna實現缺失值的刪除
    • 應用replace實現資料的替換

在這裡插入圖片描述

1 如何處理nan

  • 獲取缺失值的標記方式(NaN或者其他標記方式)

  • 如果缺失值的標記方式是NaN

    • 判斷資料中是否包含NaN:

      • pd.isnull(df),
      • pd.notnull(df)
    • 存在缺失值nan:

      • 1、刪除存在缺失值的:dropna(axis=‘rows’)

        • 注:不會修改原資料,需要接受返回值
      • 2、替換缺失值:fillna(value, inplace=True)

        • value:替換成的值
        • inplace:True:會修改原資料,False:不替換修改原資料,生成新的物件
  • 如果缺失值沒有使用NaN標記,比如使用"?"

    • 先替換‘?’為np.nan,然後繼續處理

2 電影資料的缺失值處理

  • 電影資料檔案獲取
# 讀取電影資料
movie = pd.read_csv("./data/IMDB-Movie-Data.csv")

在這裡插入圖片描述

2.1 判斷缺失值是否存在

  • pd.notnull()
pd.notnull(movie)
Rank	Title	Genre	Description	Director	Actors	Year	Runtime (Minutes)	Rating	Votes	Revenue (Millions)	Metascore
0	True	True	True	True	True	True	True	True	True	True	True	True
1	True	True	True	True	True	True	True	True	True	True	True	True
2	True	True	True	True	True	True	True	True	True	True	True	True
3	True	True	True	True	True	True	True	True	True	True	True	True
4	True	True	True	True	True	True	True	True	True	True	True	True
5	True	True	True	True	True	True	True	True	True	True	True	True
6	True	True	True	True	True	True	True	True	True	True	True	True
7	True	True	True	True	True	True	True	True	True	True	False	True
np.all(pd.notnull(movie))
  • pd.isnull()

2.2 存在缺失值nan,並且是np.nan

  • 1、刪除

pandas刪除缺失值,使用dropna的前提是,缺失值的型別必須是np.nan

# 不修改原資料
movie.dropna()

# 可以定義新的變數接受或者用原來的變數名
data = movie.dropna()
  • 2、替換缺失值
# 替換存在缺失值的樣本的兩列
# 替換填充平均值,中位數
# movie['Revenue (Millions)'].fillna(movie['Revenue (Millions)'].mean(), inplace=True)

替換所有缺失值:

for i in movie.columns:
    if np.all(pd.notnull(movie[i])) == False:
        print(i)
        movie[i].fillna(movie[i].mean(), inplace=True)

2.3 不是缺失值nan,有預設標記的

資料是這樣的:

在這裡插入圖片描述

wis = pd.read_csv("https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/breast-cancer-wisconsin.data")

以上資料在讀取時,可能會報如下錯誤:

URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:833)>

解決辦法:

# 全域性取消證照驗證
import ssl
ssl._create_default_https_context = ssl._create_unverified_context

處理思路分析:

  • 1、先替換‘?’為np.nan
    • df.replace(to_replace=, value=)
      • to_replace:替換前的值
      • value:替換後的值
# 把一些其它值標記的缺失值,替換成np.nan
wis = wis.replace(to_replace='?', value=np.nan)
  • 2、在進行缺失值的處理
# 刪除
wis = wis.dropna()

3 小結

  • isnull、notnull判斷是否存在缺失值【知道】
    • np.any(pd.isnull(movie)) # 裡面如果有一個缺失值,就返回True
    • np.all(pd.notnull(movie)) # 裡面如果有一個缺失值,就返回False
  • dropna刪除np.nan標記的缺失值【知道】
    • movie.dropna()
  • fillna填充缺失值【知道】
    • movie[i].fillna(value=movie[i].mean(), inplace=True)
  • replace替換具體某些值【知道】
    • wis.replace(to_replace="?", value=np.NaN)



八、Pandas高階處理-資料離散化

學習目標

  • 目標
    • 應用cut、qcut實現資料的區間分組
    • 應用get_dummies實現資料的one-hot編碼

1 為什麼要離散化

連續屬性離散化的目的是為了簡化資料結構,資料離散化技術可以用來減少給定連續屬性值的個數。離散化方法經常作為資料探勘的工具。

2 什麼是資料的離散化

連續屬性的離散化就是在連續屬性的值域上,將值域劃分為若干個離散的區間,最後用不同的符號或整數
值代表落在每個子區間中的屬性值。

離散化有很多種方法,這使用一種最簡單的方式去操作

  • 原始人的身高資料:165,174,160,180,159,163,192,184
  • 假設按照身高分幾個區間段:150~165, 165180,180195

這樣我們將資料分到了三個區間段,我可以對應的標記為矮、中、高三個類別,最終要處理成一個"啞變數"矩陣

3 股票的漲跌幅離散化

我們對股票每日的"p_change"進行離散化

在這裡插入圖片描述

3.1 讀取股票的資料

先讀取股票的資料,篩選出p_change資料

data = pd.read_csv("./data/stock_day.csv")
p_change= data['p_change']

3.2 將股票漲跌幅資料進行分組

在這裡插入圖片描述

使用的工具:

  • pd.qcut(data, q):
    • 對資料進行分組將資料分組,一般會與value_counts搭配使用,統計每組的個數
  • series.value_counts():統計分組次數
# 自行分組
qcut = pd.qcut(p_change, 10)
# 計算分到每個組資料個數
qcut.value_counts()

自定義區間分組:

  • pd.cut(data, bins)
# 自己指定分組區間
bins = [-100, -7, -5, -3, 0, 3, 5, 7, 100]
p_counts = pd.cut(p_change, bins)

3.3 股票漲跌幅分組資料變成one-hot編碼

  • 什麼是one-hot編碼

把每個類別生成一個布林列,這些列中只有一列可以為這個樣本取值為1.其又被稱為獨熱編碼。

把下圖中左邊的表格轉化為使用右邊形式進行表示:

在這裡插入圖片描述

  • pandas.get_dummies(data, prefix=None)

    • data:array-like, Series, or DataFrame

    • prefix:分組名字

# 得出one-hot編碼矩陣
dummies = pd.get_dummies(p_counts, prefix="rise")

在這裡插入圖片描述

4 小結

  • 資料離散化【知道】
    • 可以用來減少給定連續屬性值的個數
    • 在連續屬性的值域上,將值域劃分為若干個離散的區間,最後用不同的符號或整數值代表落在每個子區間中的屬性值。
  • qcut、cut實現資料分組【知道】
    • qcut:大致分為相同的幾組
    • cut:自定義分組區間
  • get_dummies實現啞變數矩陣【知道】



九、Pandas高階處理-合併

學習目標

  • 目標
    • 應用pd.concat實現資料的合併
    • 應用pd.merge實現資料的合併

如果你的資料由多張表組成,那麼有時候需要將不同的內容合併在一起分析

1 pd.concat實現資料合併

  • pd.concat([data1, data2], axis=1)
    • 按照行或列進行合併,axis=0為列索引,axis=1為行索引

比如我們將剛才處理好的one-hot編碼與原資料合併

在這裡插入圖片描述

# 按照行索引進行
pd.concat([data, dummies], axis=1)

2 pd.merge

  • pd.merge(left, right, how=‘inner’, on=None)
    • 可以指定按照兩組資料的共同鍵值對合並或者左右各自
    • left: DataFrame
    • right: 另一個DataFrame
    • on: 指定的共同鍵
    • how:按照什麼方式連線
Merge methodSQL Join NameDescription
leftLEFT OUTER JOINUse keys from left frame only
rightRIGHT OUTER JOINUse keys from right frame only
outerFULL OUTER JOINUse union of keys from both frames
innerINNER JOINUse intersection of keys from both frames

2.1 pd.merge合併

left = pd.DataFrame({'key1': ['K0', 'K0', 'K1', 'K2'],
                        'key2': ['K0', 'K1', 'K0', 'K1'],
                        'A': ['A0', 'A1', 'A2', 'A3'],
                        'B': ['B0', 'B1', 'B2', 'B3']})

right = pd.DataFrame({'key1': ['K0', 'K1', 'K1', 'K2'],
                        'key2': ['K0', 'K0', 'K0', 'K0'],
                        'C': ['C0', 'C1', 'C2', 'C3'],
                        'D': ['D0', 'D1', 'D2', 'D3']})
                        
# 預設內連線
result = pd.merge(left, right, on=['key1', 'key2'])

在這裡插入圖片描述

  • 左連線
result = pd.merge(left, right, how='left', on=['key1', 'key2'])

在這裡插入圖片描述

  • 右連線
result = pd.merge(left, right, how='right', on=['key1', 'key2'])

在這裡插入圖片描述

  • 外連結
result = pd.merge(left, right, how='outer', on=['key1', 'key2'])

在這裡插入圖片描述

3 總結

  • pd.concat([資料1, 資料2], axis=**)【知道】
  • pd.merge(left, right, how=, on=)【知道】
    • how – 以何種方式連線
    • on – 連線的鍵的依據是哪幾個



十、Pandas高階處理-交叉表與透視表

學習目標

  • 目標
    • 應用crosstab和pivot_table實現交叉表與透視表

1 交叉表與透視表什麼作用

探究股票的漲跌與星期幾有關?

以下圖當中表示,week代表星期幾,1,0代表這一天股票的漲跌幅是好還是壞,裡面的資料代表比例

可以理解為所有時間為星期一等等的資料當中漲跌幅好壞的比例

在這裡插入圖片描述

在這裡插入圖片描述

  • 交叉表:交叉表用於計算一列資料對於另外一列資料的分組個數(用於統計分組頻率的特殊透視表)
    • pd.crosstab(value1, value2)
  • 透視表:透視表是將原有的DataFrame的列分別作為行索引和列索引,然後對指定的列應用聚集函式
    • data.pivot_table()
    • DataFrame.pivot_table([], index=[])

2 案例分析

2.1 資料準備

  • 準備兩列資料,星期資料以及漲跌幅是好是壞資料
  • 進行交叉表計算
# 尋找星期幾跟股票張得的關係
# 1、先把對應的日期找到星期幾
date = pd.to_datetime(data.index).weekday
data['week'] = date

# 2、假如把p_change按照大小去分個類0為界限
data['posi_neg'] = np.where(data['p_change'] > 0, 1, 0)

# 通過交叉表找尋兩列資料的關係
count = pd.crosstab(data['week'], data['posi_neg'])

但是我們看到count只是每個星期日子的好壞天數,並沒有得到比例,該怎麼去做?

  • 對於每個星期一等的總天數求和,運用除法運算求出比例
# 算數運算,先求和
sum = count.sum(axis=1).astype(np.float32)

# 進行相除操作,得出比例
pro = count.div(sum, axis=0)

2.2 檢視效果

使用plot畫出這個比例,使用stacked的柱狀圖

pro.plot(kind='bar', stacked=True)
plt.show()

在這裡插入圖片描述

2.3 使用pivot_table(透視表)實現

使用透視表,剛才的過程更加簡單

# 通過透視表,將整個過程變成更簡單一些
data_pivot = data.pivot_table(['posi_neg'], index='week')
data_pivot.plot(kind="bar")
plt.show()

在這裡插入圖片描述

3 小結

  • 交叉表與透視表的作用【知道】
    • 交叉表:計算一列資料對於另外一列資料的分組個數
    • 透視表:指定某一列對另一列的關係



十一、Pandas高階處理-分組與聚合

學習目標

  • 目標
    • 應用groupby和聚合函式實現資料的分組與聚合

分組與聚合通常是分析資料的一種方式,通常與一些統計函式一起使用,檢視資料的分組情況

想一想其實剛才的交叉表與透視表也有分組的功能,所以算是分組的一種形式,只不過他們主要是計算次數或者計算比例!!看其中的效果:

在這裡插入圖片描述

1 什麼分組與聚合

在這裡插入圖片描述

2 分組API

  • DataFrame.groupby(key, as_index=False)
    • key:分組的列資料,可以多個
  • 案例:不同顏色的不同筆的價格資料
col =pd.DataFrame({'color': ['white','red','green','red','green'], 'object': ['pen','pencil','pencil','ashtray','pen'],'price1':[5.56,4.20,1.30,0.56,2.75],'price2':[4.75,4.12,1.60,0.75,3.15]})

color	object	price1	price2
0	white	pen	5.56	4.75
1	red	pencil	4.20	4.12
2	green	pencil	1.30	1.60
3	red	ashtray	0.56	0.75
4	green	pen	2.75	3.15
  • 進行分組,對顏色分組,price進行聚合
# 分組,求平均值
col.groupby(['color'])['price1'].mean()
col['price1'].groupby(col['color']).mean()

color
green    2.025
red      2.380
white    5.560
Name: price1, dtype: float64

# 分組,資料的結構不變
col.groupby(['color'], as_index=False)['price1'].mean()

color	price1
0	green	2.025
1	red	2.380
2	white	5.560

3 星巴克零售店鋪資料

現在我們有一組關於全球星巴克店鋪的統計資料,如果我想知道美國的星巴克數量和中國的哪個多,或者我想知道中國每個省份星巴克的數量的情況,那麼應該怎麼辦?

資料來源:https://www.kaggle.com/starbucks/store-locations/data

在這裡插入圖片描述

3.1 資料獲取

從檔案中讀取星巴克店鋪資料

# 匯入星巴克店的資料
starbucks = pd.read_csv("./data/starbucks/directory.csv")

3.2 進行分組聚合

# 按照國家分組,求出每個國家的星巴克零售店數量
count = starbucks.groupby(['Country']).count()

畫圖顯示結果

count['Brand'].plot(kind='bar', figsize=(20, 8))
plt.show()

在這裡插入圖片描述

假設我們加入省市一起進行分組

# 設定多個索引,set_index()
starbucks.groupby(['Country', 'State/Province']).count()

在這裡插入圖片描述

仔細觀察這個結構,與我們前面講的哪個結構類似??

與前面的MultiIndex結構類似

4 小結

  • groupby進行資料的分組【知道】
    • pandas中,拋開聚合談分組,無意義



十二、Pandas案例分析-電影案例分析

1 需求

現在我們有一組從2006年到2016年1000部最流行的電影資料

資料來源:https://www.kaggle.com/damianpanek/sunday-eda/data

  • 問題1:我們想知道這些電影資料中評分的平均分,導演的人數等資訊,我們應該怎麼獲取?
  • 問題2:對於這一組電影資料,如果我們想rating,runtime的分佈情況,應該如何呈現資料?
  • 問題3:對於這一組電影資料,如果我們希望統計電影分類(genre)的情況,應該如何處理資料?

2 實現

首先獲取匯入包,獲取資料

%matplotlib inline
import pandas  as pd 
import numpy as np
from matplotlib import pyplot as plt
#檔案的路徑
path = "./data/IMDB-Movie-Data.csv"
#讀取檔案
df = pd.read_csv(path)

2.1 問題一:我們想知道這些電影資料中評分的平均分,導演的人數等資訊,我們應該怎麼獲取?

  • 得出評分的平均分

使用mean函式

df["Rating"].mean()
  • 得出導演人數資訊

求出唯一值,然後進行形狀獲取

## 導演的人數
# df["Director"].unique().shape[0]
np.unique(df["Director"]).shape[0]

644

2.2 問題二:對於這一組電影資料,如果我們想Rating,Runtime (Minutes)的分佈情況,應該如何呈現資料?

  • 直接呈現,以直方圖的形式

選擇分數列資料,進行plot

df["Rating"].plot(kind='hist',figsize=(20,8))

在這裡插入圖片描述

  • Rating進行分佈展示

進行繪製直方圖

plt.figure(figsize=(20,8),dpi=80)
plt.hist(df["Rating"].values,bins=20)
plt.show()

修改刻度的間隔

# 求出最大最小值
max_ = df["Rating"].max()
min_ = df["Rating"].min()

# 生成刻度列表
t1 = np.linspace(min_,max_,num=21)

# [ 1.9    2.255  2.61   2.965  3.32   3.675  4.03   4.385  4.74   5.095  5.45   5.805  6.16   6.515  6.87   7.225  7.58   7.935  8.29   8.645  9.   ]

# 修改刻度
plt.xticks(t1)

# 新增網格
plt.grid()

在這裡插入圖片描述

  • Runtime (Minutes)進行分佈展示

進行繪製直方圖

plt.figure(figsize=(20,8),dpi=80)
plt.hist(df["Runtime (Minutes)"].values,bins=20)
plt.show()

修改間隔

# 求出最大最小值
max_ = df["Runtime (Minutes)"].max()
min_ = df["Runtime (Minutes)"].min()

# # 生成刻度列表
t1 = np.linspace(min_,max_,num=21)

# 修改刻度
plt.xticks(np.linspace(min_,max_,num=21))

# 新增網格
plt.grid()

在這裡插入圖片描述

2.3 問題三:對於這一組電影資料,如果我們希望統計電影分類(genre)的情況,應該如何處理資料?

  • 思路分析
    • 思路
      • 1、建立一個全為0的dataframe,列索引置為電影的分類,temp_df
      • 2、遍歷每一部電影,temp_df中把分類出現的列的值置為1
      • 3、求和
  • 1、建立一個全為0的dataframe,列索引置為電影的分類,temp_df
# 進行字串分割
temp_list = [i.split(",") for i in df["Genre"]]
# 獲取電影的分類
genre_list = np.unique([i for j in temp_list for i in j]) 

# 增加新的列
temp_df = pd.DataFrame(np.zeros([df.shape[0],genre_list.shape[0]]),columns=genre_list)
  • 2、遍歷每一部電影,temp_df中把分類出現的列的值置為1
for i in range(1000):
    #temp_list[i] ['Action','Adventure','Animation']
    temp_df.ix[i,temp_list[i]]=1
print(temp_df.sum().sort_values())
  • 3、求和,繪圖
temp_df.sum().sort_values(ascending=False).plot(kind="bar",figsize=(20,8),fontsize=20,colormap="cool")


Musical        5.0
Western        7.0
War           13.0
Music         16.0
Sport         18.0
History       29.0
Animation     49.0
Family        51.0
Biography     81.0
Fantasy      101.0
Mystery      106.0
Horror       119.0
Sci-Fi       120.0
Romance      141.0
Crime        150.0
Thriller     195.0
Adventure    259.0
Comedy       279.0
Action       303.0
Drama        513.0
dtype: float64

在這裡插入圖片描述

相關文章