1. 程式人生 > 其它 >Python pandas(一)- 預備知識

Python pandas(一)- 預備知識

技術標籤:PYTHON學習python列表

一、Python 基礎

1.1 列表推導式

列表推導式將多行for迴圈寫在一行上,使程式看起來簡潔,需注意:多層巢狀時,易讀性差,需要注意巢狀的順序,列表推導式內部也會有列表推導式,用 [] 區分

  1. [ ? for i in ?] 。其中,第一個 ? 為對映函式,其輸入為後面 i 指代的內容,第二個 ? 表示迭代的物件。
[i ** 2 for i in range(5)]
# 輸出: [0, 2, 4, 6, 8]
  1. 列表表示式多層巢狀
[m + '_' + n for m in ['a', 'b'] for n in ['c', 'd']]
# 輸出:['a_c', 'a_d', 'b_c', 'b_d']

其中,第一個第一個 for 為外層迴圈,第二個為內層迴圈。
對應練習題:練習題1

1.2 條件賦值語句
  1. 形式為:value = a if condition else b
value = 'cat' if 2>1 else 'dog'
value
# 輸出:'cat'

value = 'cat' if 2<1 else 'dog'
value
# 輸出:'dog'
  1. 條件賦值與for迴圈
    練習1:列表中最大值為5,將大於5的數值改寫為5
L1 = [1, 2, 3, 4, 5, 6, 7]
res1 = [i if
i <= 5 else 5 for i in L1] res1 # 輸出:[1, 2, 3, 4, 5, 5, 5]

練習2:去除列表中的大於5的元素及重複元素

# (1) 用 “條件賦值語句”
L2 = [1, 7, 4, 3, 5, 6, 7, 1, 3]
L2 = sorted(list(set(L2)), reverse=False)
res2 = [i  if i <=5 else 6 for i in L2]
try:
    res2 = res2[0: res2.index(6)]
except:
    res2 = res2
res2
# 輸出:[1, 3, 4, 5]
# (2) 基於numpy
import numpy as np
L3 = [1, 7, 4, 3, 5, 6, 7, 1, 3]
L3 = np.array(L3)
res3 = list(set(L3[L3 <= 5]))
res3
# 輸出:[1, 3, 4, 5]
1.3 匿名函式與map方法

當函式的定義具有明顯的對映關係的時候,用匿名函式 lambda 可以簡潔表示:

list(map(lambda x: 2*x, range(5)))
# 輸出:[0, 2, 4, 6, 8]

注意:map物件需要通過list轉為列表

1.4 zip 物件和enumerate
  1. 在 Python 3.x 中為了減少記憶體,zip() 返回的是一個迭代器,通過 tuple, list 可以得到相應的打包結果:
L1, L2, L3 = list('abc'), list('def'), list('hij')
list(zip(L1, L2, L3))
# 輸出:[('a', 'd', 'h'), ('b', 'e', 'i'), ('c', 'f', 'j')]
dict(zip(L1, L2))
# 輸出字典對映:{'a': 'd', 'b': 'e', 'c': 'f'}
  1. 在 for 迴圈中,如果想要同時遍歷多個 list,可用 zip 函式進行迭代打包:
list1 = list('123')
list2 = list('abc')
for i, j in zip(list1, list2):
    print(i, j)
# 輸出: 1 a
#       2 b
#       3 c
  1. zip() 函式解壓
L1, L2, L3 = list('abc'), list('def'), list('hij')
zipped = list(zip(L1, L2, L3))
zipped
# 輸出:[('a', 'd', 'h'), ('b', 'e', 'i'), ('c', 'f', 'j')]

# 解壓
list(zip(*zipped))
# 輸出:[('a', 'b', 'c'), ('d', 'e', 'f'), ('h', 'i', 'j')]
  1. enumerate方法
    既要遍歷索引又要遍歷元素是採用 enumerate 方法。
L = ['It', 'is', 'a', 'dog', '!']
for index, value in enumerate(L):
     print(index, value)
# 輸出: 0 It
#       1 is
#       2 a
#       3 dog
#       4 !

二、Numpy 基礎

2.1 np陣列的生成方式
  1. 生成隨機資料
import numpy as np
L1 = np.linspace(1,5,11)       # 起始、終止(包含)、樣本個數
L2 = np.arange(1,7,2)          # 起始、終止(不包含)、步長
L3 = np.zeros((2,3))           # 2 * 3 維度的0矩陣,輸入的是元組(2,3)
L4 = np.zeros(3)
L5 = np.eye(3)                 # 3 * 3 的單位矩陣,主對角線上的值為1
L6 = np.eye(3, k=1)            # 偏移主對角線1個單位的偽單位矩陣
L7 = np.full((2,3), 10)        # 大小為2 * 3,值為10的矩陣
L8 = np.full((2,3), [1,2,3])   # 大小為2 * 3,每一行的取值為[1,2,3]
# 均勻分佈
L_1 = np.random.rand(3)         # 生成服從0-1 均勻分佈 的3個隨機數
L_2 = np.random.rand(3, 3)      # 生成服從0-1均勻分佈,大小為3 * 3的隨機矩陣

a, b = 5, 15
L_3 = (b - a) * np.random.rand(3) + a  # 服從區間 a 到 b 上的均勻分佈的3個隨機數
# 正太分佈
L_4 = np.random.randn(3)       # 生成服從 0-1 正態分佈 的3個隨機數
L_5 = np.random.randn(2, 3)

sigma, mu = 2.5, 3
L_6 = mu + np.random.randn(3) * sigma   # 標準差為sigma,均值為mu的正態分佈
# 隨機整數
low, high, size = 5, 10, (2,3)
L9 = np.random.randint(low, high, size)
  1. 隨機選擇資料 choice
    choice 可以從給定的列表中,以一定概率和方式抽取結果,當不指定概率時為均勻取樣,預設抽取方式為有放回抽樣;
    應用:ML中劃分 train set、valid set、test set 時,可用隨機抽取樣本的方式,python實現上用 np.choice
my_list = ['a', 'b', 'c', 'd']
# 從my_list中,以概率p抽取2個數據
np.random.choice(my_list, 2, replace=False, p=[0.1, 0.7, 0.1 ,0.1])
# 輸出:array(['b', 'c'], dtype='<U1')

np.random.choice(my_list, (3,3))
  1. 隨機種子 - 使結果可復現
np.random.seed(0)
np.random.rand()
# 輸出:0.5488135039273248
np.random.seed(0)
np.random.rand()
# 輸出:0.5488135039273248

同時設定隨機種子為0,生成的隨機數的結果相同

2.2 變形與合併
  1. 變形
# 轉置 .T
np.zeros((2,3)).T
# reshape, 把原陣列按照新的維度重新排列
target = np.arange(8).reshape(2,4)
target
# 輸出:array([[0, 1, 2, 3],
#              [4, 5, 6, 7]])

.reshape 在使用時有兩種模式,分別為C模式F模式,分別以逐行逐列的順序進行填充讀取。

target.reshape((4,2), order='C') # 按照行讀取和填充,0 1 2 3 4 5 6 7 8 9 
# 輸出:array([[0, 1],
#              [2, 3],
#              [4, 5],
#              [6, 7]])

target.reshape((4,2), order='F') # 按照列讀取和填充,0 2 4 6 1 3 5 7
# 輸出:array([[0, 2],
#              [4, 6],
#              [1, 3],
#              [5, 7]])
  1. 合併
    學習資料中給出的是 **r_ ** 和 **c_ ** 進行陣列的合併:
# 對於二維陣列,r_和c_分別表示上下合併和左右合併
np.r_[np.zeros((2,3)),np.zeros((2,3))]
# 輸出:array([[0., 0., 0.],
#             [0., 0., 0.],
#             [0., 0., 0.],
#             [0., 0., 0.]])

np.c_[np.zeros((2,3)),np.zeros((2,3))]
# 輸出:array([[0., 0., 0., 0., 0., 0.],
#              [0., 0., 0., 0., 0., 0.]])
# 對於一維陣列,r_和c_
np.r_[np.zeros(3),np.zeros(3)]
# 輸出:array([0., 0., 0., 0., 0., 0.])

np.c_[np.zeros(3),np.zeros(3)]
# array([[0., 0.],
#        [0., 0.],
#        [0., 0.]])

除此之外,np.vstack()np.hstack() 也用於陣列的合併

np.vstack((np.zeros((2,3)),np.zeros((2,3))))
# 輸出:array([[0., 0., 0.],
#              [0., 0., 0.],
#              [0., 0., 0.],
#              [0., 0., 0.]])

np.hstack((np.zeros((2,3)),np.zeros((2,3))))
# 輸出:array([[0., 0., 0., 0., 0., 0.],
#              [0., 0., 0., 0., 0., 0.]])
2.3 陣列的切片與索引

list[start : end : step] 切片,還可以直接傳入列表指定某個維度的索引進行切片;
利用 np.ix_ 在對應的維度上使用布林索引,但此時不能使用slice切片:

target = np.arange(9).reshape(3,3)
target
# 輸出:array([[0, 1, 2],
#              [3, 4, 5],
#              [6, 7, 8]])
target[np.ix_([True, False, True])]  # 輸出target的前兩行
# 輸出:array([[0, 1, 2],
#              [6, 7, 8]])

target[np.ix_([True, False, True], [True, False, True])]  # 第一個布林為行索引,第二個布林為列索引
# 等價於 target[np.ix_([0,2], [True, False, True])]   這裡的[0,2]不能是切片,只能單獨索引某一個維度
# 輸出:array([[0, 2],
#              [6, 8]])
2.4 一些常用函式
# (1)np.where 條件函式查詢,有點類似於條件賦值語句
a = np.array([3,1,-1,0])
np.where(a>0, a, 5)     # 滿足a>0則對應位置填充a對應的元素,否則填充5
# 輸出:array([3, 1, 5, 5])
# (2)np.nonzero() 返回非零數字的索引
a = np.array([-2,-5,0,1,3,-1])
np.nonzero(a)   # 索引為2的地方為0
# 輸出:(array([0, 1, 3, 4, 5], dtype=int64),)

# (3)np.argmax(), np.argmin() 返回最大和最小數的索引
a.argmax()  # 4
a.argmin()  # 1
# (4) np.any(), np.all()
a = np.array([0,1])
a.any()  # any 指當序列至少 存在一個 True 或非零元素時返回 True,否則返回 False
# 輸出:True 

a.all()  # all 指當序列元素全為 True 或非零元素時返回 True,否則返回 False
# 輸出:False
# (5) np.cumprod() 累乘; np.cumsum() 累加
a = np.array([1,3,3,4])
a.cumprod()    
# 輸出:array([ 1,  3,  9, 36], dtype=int32)

a.cumsum()
# 輸出:array([ 1,  3,  6, 10], dtype=int32)
# (6) np.diff() 和前一個元素做差,由於第一個元素為缺失值,因此在預設情況下,返回長度是原陣列減1
np.diff(a)
# 輸出:array([2, 0, 1])

np.diff() 的可能應用場景:時間序列預測 or 分類問題中構造特徵;例如,基於銀行存款資料預測某人是否存在貸款違約風險,可用當月存款 - 上月存款,構造新的特徵。

# (7) 相關係數,協方差
target1 = np.array([1,3,5,9])
target2 = np.array([1,5,3,-9])
np.cov(target1, target2)       # 協方差
np.corrcoef(target1, target2)  # 相關係數
2.5 廣播機制

廣播機制用於處理兩個不同維度陣列之間的操作;

  1. 標量和陣列
# 一個標量和陣列進行運算時,標量會自動把大小擴充為陣列大小,之後進行逐元素操作:
res = 3 * np.ones((2,2)) + 1
res
# 輸出:array([[4., 4.],
#              [4., 4.]])
  1. 二維陣列和二維陣列
    當兩個陣列維度完全一致時,使用對應元素的操作,否則會報錯;
    除非其中的某個陣列的維度是