­

數據分析之路—python基礎學習

  • 2019 年 10 月 8 日
  • 筆記

大數據分析、底層架構、設計思路,本文作者(大數據分析師——廉小寶)帶你探路。 —— 23號老闆

原創:a廉小寶

Python安裝與使用

Python安裝:直接安裝Anaconda環境可以方便很多,Anaconda內置了很多Python包,使用起來很方便,另外推薦使用Python3版本,Python2目前已經停更。

推薦工具:一些小的實驗可以在Jupyter Notebook上進行,工程項目可以使用Pycharm,方便調試 。 安裝鏈接

python數據類型

1.基本數據類型

計算機顧名思義就是可以做數學計算的機器,因此,計算機程序理所當然地可以處理各種數值。但是,計算機能處理的遠不止數值,還可以處理文本、圖形、音頻、視頻、網頁等各種各樣的數據,不同的數據,需要定義不同的數據類型。在Python中,能夠直接處理的數據類型有以下幾種:

整數

Python可以處理任意大小的整數,當然包括負整數,在程序中的表示方法和數學上的寫法一模一樣,例如:1,100,-8080,0,等等。

計算機由於使用二進制,所以,有時候用十六進制表示整數比較方便,十六進制用0x前綴和0-9,a-f表示,例如:0xff00,0xa5b4c3d2,等等。

浮點數

浮點數也就是小數,之所以稱為浮點數,是因為按照科學記數法表示時,一個浮點數的小數點位置是可變的,比如,1.23×109和12.3×108是完全相等的。浮點數可以用數學寫法,如1.23,3.14,-9.01,等等。但是對於很大或很小的浮點數,就必須用科學計數法表示,把10用e替代,1.23×109就是1.23e9,或者12.3e8,0.000012可以寫成1.2e-5,等等。

字符串

字符串是以單引號』或雙引號"括起來的任意文本,比如』abc』,「xyz"等等。請注意,』'或」「本身只是一種表示方式,不是字符串的一部分,因此,字符串』abc』只有a,b,c這3個字符。如果』本身也是一個字符,那就可以用」"括起來,比如"I』m OK"包含的字符是I,』,m,空格,O,K這6個字符。

2.數據存儲結構

list

Python內置的一種數據類型是列表:list。list是一種有序的集合,可以隨時添加和刪除其中的元素。

比如,一列數字,就可以用一個list表示:

a = [1,2,3,4,5]  print(a)  

用索引來訪問list中每一個位置的元素,記得索引是從0開始的:

print(a[0])  print(a[1:3])  

記住list的索引範圍是0:len(list)。

Tuple

另一種有序列表叫元組:tuple。tuple和list非常類似,但是tuple一旦初始化就不能修改。

a = (1, 2, 3, 4, 5)  print(a)  

dict

Python內置了字典:dict的支持,dict全稱dictionary,在其他語言中也稱為map,使用鍵-值(key-value)存儲,具有極快的查找速度。

names = ['Michael', 'Bob', 'Tracy']  scores = [95, 75, 85]  a = dict(zip(names, scores))  

dict也可以通過直接命名的方式定義,更為直接:

d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}  d['Bob']  

通過檢索dict的key可以直接訪問其對應的value。

dict可以存儲不同類型的數據,這是和前面的list和tuple完全不同的地方。

set

set和dict類似,也是一組key的集合,但不存儲value。由於key不能重複,所以,在set中,沒有重複的key。

重複元素在set中自動被過濾:

s = set([1, 1, 2, 2, 3, 3])  s  

數據分析基礎之Pandas

Pandas概述

Pandas 是一個 Python 的包,提供快速、靈活和富有表現力的數據結構,旨在使「關係」或「標記」數據的使用既簡單又直觀。它旨在成為在Python中進行實際,真實世界數據分析的基礎高級構建模塊。此外,它還有更宏遠的目標,即成為超過任何語言的最強大,最靈活的開源數據分析/操作工具。它已朝着這個目標邁進。

pandas非常適合許多不同類型的數據:

  • 具有異構類型列的表格數據,如SQL表或Excel電子表格。
  • 有序和無序(不一定是固定頻率)時間序列數據。
  • 具有行和列標籤的任意矩陣數據(均勻類型或異構)。
  • 任何其他形式的觀察/統計數據集。實際上不需要將數據標記為放置在Pandas數據結構中。

Pandas 的兩個主要數據結構,Series(1維)和DataFrame(2維),處理金融,統計,社會科學和許多工程領域中的絕大多數典型用例。對於R用戶,DataFrame提供R的data.frame提供的所有內容以及更多內容。Pandas建立在NumPy之上,旨在與許多其他第三方庫完美地集成在科學計算環境中。

以下是Pandas做夠勝任的一些事情:

  • 在浮點和非浮點數據中輕鬆處理缺失數據(表示為NaN)。
  • 大小可變性:可以從DataFrame和更高維度的對象中插入和刪除。
  • 自動和顯式數據對齊:對象可以明確地與一組標籤對齊,或者用戶可以簡單地忽略標籤,讓Series,DataFrame等在計算中自動對齊數據
  • 強大,靈活的組(group by)功能,可對數據集執行拆分應用組合操作,用於聚合和轉換數據。
  • 輕鬆將其他Python和NumPy數據結構中的不規則,不同索引數據轉換為DataFrame對象。
  • 基於智能標籤的切片,花式索引和子集大數據集。
  • 直觀合併和加入數據集。
  • 靈活的重塑和數據集的旋轉。
  • 軸的分層標記(每個刻度可能有多個標籤)。
  • 強大的IO工具,用於從平面文件(CSV和分隔)、Excel文件、數據庫以及能從超快的HDF5格式中保存或加載數據。
  • 特定時間序列功能:日期範圍生成和頻率轉換、移動窗口統計、移動窗口線性回歸、日期轉換和滯後等。

其中許多技術都是為了解決使用其他語言/科研環境時經常遇到的缺點。對於數據科學家來說,處理數據通常分為多個階段:整理和清理數據,分析/建模數據,然後將分析結果組織成適合繪圖或表格顯示的形式。Pandas 是完成所有這些任務的理想工具。

Pandas操作

導入相關包

  import pandas as pd  import numpy as np  

對象創建

通過傳入一些值的列表來創建一個Series,Pandas會自動創建一個默認的整數索引:

s = pd.Series([1, 3, 5, np.nan, 6, 8])  print(s)  
0    1.0  1    3.0  2    5.0  3    NaN  4    6.0  5    8.0  dtype: float64  

通過傳遞帶有日期時間索引和帶標籤列的NumPy數組來創建DataFrame:

dates = pd.date_range('20190725', periods=6)  
dates  
DatetimeIndex(['2019-07-25', '2019-07-26', '2019-07-27', '2019-07-28',                 '2019-07-29', '2019-07-30'],                dtype='datetime64[ns]', freq='D')  
df = pd.DataFrame(np.random.rand(6,4),index=dates, columns=list('ABCD'))  
df  

A

B

C

D

2019-07-25

0.030035

0.364846

0.385114

0.892197

2019-07-26

0.264333

0.959643

0.418979

0.512688

2019-07-27

0.829229

0.488593

0.424240

0.734755

2019-07-28

0.641315

0.307451

0.582599

0.084260

2019-07-29

0.070572

0.937610

0.515065

0.961442

2019-07-30

0.906944

0.143410

0.875313

0.430607

通過傳遞可以轉化為類似Series的dict對象來創建DataFrame:

df2 = pd.DataFrame({      'A': 1.,      'B': pd.Timestamp('20190722'),      'C': pd.Series(1, index=list(range(4)), dtype='float32'),      'D': np.array([3] * 4, dtype='int32'),      'E':pd.Categorical(["Luffy","Zoro","Nami","Robin"]),      'F':'onepice'  })  
df2  

A

B

C

D

E

F

0

1.0

2019-07-22

1.0

3

Luffy

onepice

1

1.0

2019-07-22

1.0

3

Zoro

onepice

2

1.0

2019-07-22

1.0

3

Nami

onepice

3

1.0

2019-07-22

1.0

3

Robin

onepice

查看數據

df.head() # 查看起始的幾個  df.tail() # 查看末尾的幾個  

A

B

C

D

2019-07-26

0.264333

0.959643

0.418979

0.512688

2019-07-27

0.829229

0.488593

0.424240

0.734755

2019-07-28

0.641315

0.307451

0.582599

0.084260

2019-07-29

0.070572

0.937610

0.515065

0.961442

2019-07-30

0.906944

0.143410

0.875313

0.430607

df.index  
DatetimeIndex(['2019-07-25', '2019-07-26', '2019-07-27', '2019-07-28',                 '2019-07-29', '2019-07-30'],                dtype='datetime64[ns]', freq='D')  
df.columns  
Index(['A', 'B', 'C', 'D'], dtype='object')  
df.describe()  

A

B

C

D

count

6.000000

6.000000

6.000000

6.000000

mean

0.457071

0.533592

0.533551

0.602658

std

0.385674

0.340186

0.182570

0.327549

min

0.030035

0.143410

0.385114

0.084260

25%

0.119012

0.321800

0.420294

0.451127

50%

0.452824

0.426720

0.469652

0.623721

75%

0.782250

0.825356

0.565715

0.852836

max

0.906944

0.959643

0.875313

0.961442

df.to_dict  
<bound method DataFrame.to_dict of                    A         B         C         D  2019-07-25  0.030035  0.364846  0.385114  0.892197  2019-07-26  0.264333  0.959643  0.418979  0.512688  2019-07-27  0.829229  0.488593  0.424240  0.734755  2019-07-28  0.641315  0.307451  0.582599  0.084260  2019-07-29  0.070572  0.937610  0.515065  0.961442  2019-07-30  0.906944  0.143410  0.875313  0.430607>  

Sorting by an axis:

df.sort_index(axis=1,ascending=False)  

D

C

B

A

2019-07-25

0.892197

0.385114

0.364846

0.030035

2019-07-26

0.512688

0.418979

0.959643

0.264333

2019-07-27

0.734755

0.424240

0.488593

0.829229

2019-07-28

0.084260

0.582599

0.307451

0.641315

2019-07-29

0.961442

0.515065

0.937610

0.070572

2019-07-30

0.430607

0.875313

0.143410

0.906944

Sorting by values:

df.sort_values(by='C')  

A

B

C

D

2019-07-25

0.030035

0.364846

0.385114

0.892197

2019-07-26

0.264333

0.959643

0.418979

0.512688

2019-07-27

0.829229

0.488593

0.424240

0.734755

2019-07-29

0.070572

0.937610

0.515065

0.961442

2019-07-28

0.641315

0.307451

0.582599

0.084260

2019-07-30

0.906944

0.143410

0.875313

0.430607

標記

選擇一個column:df[『A』]或者df.A

Sorting by values:

.loc() 具有多種訪問方式,如 –

  • 單個標量標籤
  • 標籤列表
  • 切片對象
  • 一個布爾數組

loc需要兩個單/列表/範圍運算符,用","分隔。第一個表示行,第二個表示列

df.loc[dates[0]]  
A    0.030035  B    0.364846  C    0.385114  D    0.892197  Name: 2019-07-25 00:00:00, dtype: float64  
df.loc[:,['A','B']]  

A

B

2019-07-25

0.030035

0.364846

2019-07-26

0.264333

0.959643

2019-07-27

0.829229

0.488593

2019-07-28

0.641315

0.307451

2019-07-29

0.070572

0.937610

2019-07-30

0.906944

0.143410

df.loc['20190726':'20190728',['A','B']]  

A

B

2019-07-26

0.264333

0.959643

2019-07-27

0.829229

0.488593

2019-07-28

0.641315

0.307451

.iloc()各種訪問方式如下 –

  • 整數
  • 整數列表
  • 系列值
df.iloc[[1,2,4],[0,2]]  

A

C

2019-07-26

0.264333

0.418979

2019-07-27

0.829229

0.424240

2019-07-29

0.070572

0.515065

df.iloc[1:3,:]  

A

B

C

D

2019-07-26

0.264333

0.959643

0.418979

0.512688

2019-07-27

0.829229

0.488593

0.424240

0.734755

df.iloc[:,1:3]  

B

C

2019-07-25

0.364846

0.385114

2019-07-26

0.959643

0.418979

2019-07-27

0.488593

0.424240

2019-07-28

0.307451

0.582599

2019-07-29

0.937610

0.515065

2019-07-30

0.143410

0.875313

使用一個column的值去選擇數據:

df[df.A>0]  

A

B

C

D

2019-07-25

0.030035

0.364846

0.385114

0.892197

2019-07-26

0.264333

0.959643

0.418979

0.512688

2019-07-27

0.829229

0.488593

0.424240

0.734755

2019-07-28

0.641315

0.307451

0.582599

0.084260

2019-07-29

0.070572

0.937610

0.515065

0.961442

2019-07-30

0.906944

0.143410

0.875313

0.430607

df[df>0]  

A

B

C

D

2019-07-25

0.030035

0.364846

0.385114

0.892197

2019-07-26

0.264333

0.959643

0.418979

0.512688

2019-07-27

0.829229

0.488593

0.424240

0.734755

2019-07-28

0.641315

0.307451

0.582599

0.084260

2019-07-29

0.070572

0.937610

0.515065

0.961442

2019-07-30

0.906944

0.143410

0.875313

0.430607

通過label設置value:

df.at[dates[0], 'A'] = 0  
df  

A

B

C

D

2019-07-25

0.000000

0.364846

0.385114

0.892197

2019-07-26

0.264333

0.959643

0.418979

0.512688

2019-07-27

0.829229

0.488593

0.424240

0.734755

2019-07-28

0.641315

0.307451

0.582599

0.084260

2019-07-29

0.070572

0.937610

0.515065

0.961442

2019-07-30

0.906944

0.143410

0.875313

0.430607

通過位置設置value:

df.iat[0,1] = 0  
df  

A

B

C

D

2019-07-25

0.000000

0.000000

0.385114

0.892197

2019-07-26

0.264333

0.959643

0.418979

0.512688

2019-07-27

0.829229

0.488593

0.424240

0.734755

2019-07-28

0.641315

0.307451

0.582599

0.084260

2019-07-29

0.070572

0.937610

0.515065

0.961442

2019-07-30

0.906944

0.143410

0.875313

0.430607

通過numpy數組來設置:

df.loc[:, 'D'] = np.array([5] * len(df))  
df  

A

B

C

D

2019-07-25

0.000000

0.000000

0.385114

5

2019-07-26

0.264333

0.959643

0.418979

5

2019-07-27

0.829229

0.488593

0.424240

5

2019-07-28

0.641315

0.307451

0.582599

5

2019-07-29

0.070572

0.937610

0.515065

5

2019-07-30

0.906944

0.143410

0.875313

5

缺失值

刪除缺失數據

df.dropna(how='any')  

A

B

C

D

2019-07-25

0.000000

0.000000

0.385114

5

2019-07-26

0.264333

0.959643

0.418979

5

2019-07-27

0.829229

0.488593

0.424240

5

2019-07-28

0.641315

0.307451

0.582599

5

2019-07-29

0.070572

0.937610

0.515065

5

2019-07-30

0.906944

0.143410

0.875313

5

填充/替換缺失數據

df.fillna(value=10)  

A

B

C

D

2019-07-25

0.000000

0.000000

0.385114

5

2019-07-26

0.264333

0.959643

0.418979

5

2019-07-27

0.829229

0.488593

0.424240

5

2019-07-28

0.641315

0.307451

0.582599

5

2019-07-29

0.070572

0.937610

0.515065

5

2019-07-30

0.906944

0.143410

0.875313

5

判斷是否有缺失值數據

pd.isna(df)  

A

B

C

D

2019-07-25

False

False

False

False

2019-07-26

False

False

False

False

2019-07-27

False

False

False

False

2019-07-28

False

False

False

False

2019-07-29

False

False

False

False

2019-07-30

False

False

False

False

Apply

df.apply(np.cumsum)  

A

B

C

D

2019-07-25

0.000000

0.000000

0.385114

5

2019-07-26

0.264333

0.959643

0.804092

10

2019-07-27

1.093562

1.448236

1.228332

15

2019-07-28

1.734877

1.755688

1.810931

20

2019-07-29

1.805448

2.693298

2.325995

25

2019-07-30

2.712393

2.836708

3.201309

30

df.apply(lambda x: x.max() - x.min())  
A    0.906944  B    0.959643  C    0.490200  D    0.000000  dtype: float64  

查看錶格某列中有多少個不同值的快捷方法,並計算每個不同值有在該列中有多少重複值。

s = pd.Series(np.random.randint(0, 7, size=10))  
s  
0    3  1    3  2    4  3    4  4    2  5    2  6    0  7    6  8    4  9    5  dtype: int64  
s.value_counts()  
3    4  4    3  5    2  2    1  dtype: int64  

合併

concat:

df3 = pd.DataFrame(np.random.randn(10, 4))  
df3  

0

1

2

3

0

0.546509

-0.645993

1.569857

-0.059439

1

3.143148

-0.357604

-0.610698

-1.032072

2

-0.593522

0.453311

0.033460

-1.163151

3

0.222209

0.542827

1.220938

0.540577

4

0.770124

-1.044302

-0.684126

0.990673

5

-0.324735

1.688151

1.202889

0.632073

6

0.385171

1.368965

-0.049633

0.697233

7

0.428143

0.012934

-0.745038

-0.570553

8

0.396524

0.804365

-1.310140

-0.246317

9

-0.438507

0.887196

1.272626

-2.558894

pieces = [df3[:3], df3[3:7], df3[7:]]  
pieces  
[          0         1         2         3   0  0.546509 -0.645993  1.569857 -0.059439   1  3.143148 -0.357604 -0.610698 -1.032072   2 -0.593522  0.453311  0.033460 -1.163151,             0         1         2         3   3  0.222209  0.542827  1.220938  0.540577   4  0.770124 -1.044302 -0.684126  0.990673   5 -0.324735  1.688151  1.202889  0.632073   6  0.385171  1.368965 -0.049633  0.697233,             0         1         2         3   7  0.428143  0.012934 -0.745038 -0.570553   8  0.396524  0.804365 -1.310140 -0.246317   9 -0.438507  0.887196  1.272626 -2.558894]  
pd.concat(pieces)  

0

1

2

3

0

0.546509

-0.645993

1.569857

-0.059439

1

3.143148

-0.357604

-0.610698

-1.032072

2

-0.593522

0.453311

0.033460

-1.163151

3

0.222209

0.542827

1.220938

0.540577

4

0.770124

-1.044302

-0.684126

0.990673

5

-0.324735

1.688151

1.202889

0.632073

6

0.385171

1.368965

-0.049633

0.697233

7

0.428143

0.012934

-0.745038

-0.570553

8

0.396524

0.804365

-1.310140

-0.246317

9

-0.438507

0.887196

1.272626

-2.558894

merge:

left = pd.DataFrame({'key': ['foo', 'foo'], 'lval': [1, 2]})  
right = pd.DataFrame({'key': ['foo', 'foo'], 'rval': [4, 5]})  
left  

key

lval

0

foo

1

1

foo

2

right  

key

rval

0

foo

4

1

foo

5

pd.merge(left, right, on='key')  

key

lval

rval

0

foo

1

4

1

foo

1

5

2

foo

2

4

3

foo

2

5

append:

df = pd.DataFrame(np.random.randn(8, 4), columns=['A', 'B', 'C', 'D'])  
df  

A

B

C

D

0

-0.580808

-0.929980

0.582348

-0.535886

1

-1.221695

-0.739676

-2.285674

1.760386

2

-0.105866

0.978615

0.793799

1.810907

3

-0.244317

0.806360

0.966249

0.662066

4

-0.134750

-0.596918

-0.260338

0.532753

5

-0.052537

1.517903

-1.092491

-0.634890

6

0.751423

-0.674670

-0.266553

-0.247528

7

0.677052

-1.403007

0.252095

-1.426274

s = df.iloc[4]  
s  
A   -0.134750  B   -0.596918  C   -0.260338  D    0.532753  Name: 4, dtype: float64  
df.append(s, ignore_index=True)  

A

B

C

D

0

-0.580808

-0.929980

0.582348

-0.535886

1

-1.221695

-0.739676

-2.285674

1.760386

2

-0.105866

0.978615

0.793799

1.810907

3

-0.244317

0.806360

0.966249

0.662066

4

-0.134750

-0.596918

-0.260338

0.532753

5

-0.052537

1.517903

-1.092491

-0.634890

6

0.751423

-0.674670

-0.266553

-0.247528

7

0.677052

-1.403007

0.252095

-1.426274

8

-0.134750

-0.596918

-0.260338

0.532753

分組

df = pd.DataFrame({'A': ['bao', 'xiao', 'bao', 'xiao',                            'bao', 'xiao', 'bao', 'bao'],                     'B': ['one', 'one', 'two', 'three',                     'two', 'two', 'one', 'three'],                     'C': np.random.randn(8),                     'D': np.random.randn(8)                    })  
df  

A

B

C

D

0

bao

one

0.213947

-0.725881

1

xiao

one

0.059765

0.279252

2

bao

two

0.331073

-0.106657

3

xiao

three

-1.168653

-0.493226

4

bao

two

1.149379

0.214320

5

xiao

two

-0.779205

-1.242145

6

bao

one

1.676725

-1.061910

7

bao

three

-0.085045

0.155202

df.groupby('A').sum()  

C

D

A

bao

3.286079

-1.524925

xiao

-1.888093

-1.456119

數據輸入/輸出

CSV

df.to_csv('bao.csv')  
pd.read_csv('bao.csv')  

Unnamed: 0

A

B

C

D

0

0

bao

one

0.213947

-0.725881

1

1

xiao

one

0.059765

0.279252

2

2

bao

two

0.331073

-0.106657

3

3

xiao

three

-1.168653

-0.493226

4

4

bao

two

1.149379

0.214320

5

5

xiao

two

-0.779205

-1.242145

6

6

bao

one

1.676725

-1.061910

7

7

bao

three

-0.085045

0.155202

HDF5

df.to_hdf('bao.h5', 'df')  
pd.read_hdf('bao.h5', 'df')  

A

B

C

D

0

bao

one

0.213947

-0.725881

1

xiao

one

0.059765

0.279252

2

bao

two

0.331073

-0.106657

3

xiao

three

-1.168653

-0.493226

4

bao

two

1.149379

0.214320

5

xiao

two

-0.779205

-1.242145

6

bao

one

1.676725

-1.061910

7

bao

three

-0.085045

0.155202

Excle

df.to_excel('bao.xlsx', sheet_name='Sheet1')  
pd.read_excel('bao.xlsx', 'Sheet1', index_col=None, na_values=['NA'])  

A

B

C

D

0

bao

one

0.213947

-0.725881

1

xiao

one

0.059765

0.279252

2

bao

two

0.331073

-0.106657

3

xiao

three

-1.168653

-0.493226

4

bao

two

1.149379

0.214320

5

xiao

two

-0.779205

-1.242145

6

bao

one

1.676725

-1.061910

7

bao

three

-0.085045

0.155202