python-資料分析-Pandas-1、Series物件

little小新發表於2024-06-09
Pandas 是 Wes McKinney 在2008年開發的一個強大的分析結構化資料的工具集。Pandas 以 NumPy 為基礎(實現資料儲存和運算)
提供了專門用於資料分析的型別、方法和函式,對資料分析和資料探勘提供了很好的支援;
同時 pandas 還可以跟資料視覺化工具 matplotlib 很好的整合在一起,非常輕鬆愉快的實現資料視覺化呈現。

Pandas 核心的資料型別是Series(資料系列)、DataFrame(資料窗/資料框),分別用於處理一維和二維的資料
除此之外,還有一個名為Index的型別及其子型別,它們為Series和DataFrame提供了索引功能。
日常工作中DataFrame使用得最為廣泛,因為二維的資料結構剛好可以對應有行有列的表格。
Series和DataFrame都提供了大量的處理資料的方法,資料分析師以此為基礎,可以實現對資料的篩選、合併、拼接、清洗、預處理、聚合、透視和視覺化等各種操作

Series 物件

# -*- coding: utf-8 -*-


#建立Series物件""
#Pandas 庫中的Series物件可以用來表示一維資料結構,但是多了索引和一些額外的功能。
#Series型別的內部結構包含了兩個陣列,其中一個用來儲存資料,另一個用來儲存資料的索引。我們可以透過列表或陣列建立Series物件

import numpy
import pandas
#說明:Series構造器中的data參數列示資料,index參數列示資料的索引,相當於資料對應的標籤。
ser1 = pandas.Series(data=[120, 380, 250, 360], index=['一季度', '二季度', '三季度', '四季度'])
print(ser1)
'''
一季度    120
二季度    380
三季度    250
四季度    360
dtype: int64
'''

print('---------------------------------------------')

#透過字典建立Series物件。
#說明:透過字典建立Series物件時,字典的鍵就是資料的標籤(索引),鍵對應的值就是資料。
ser2 = pandas.Series({'一季度': 320, '二季度': 380, '三季度': 250, '四季度': 360})
print(ser2)

print('---------------------------------------------')

#Series物件的運算
#標量運算
#我們嘗試給剛才的ser1每個季度加上10,程式碼如下所示。
ser1 += 10
print(ser1, '\n')
'''
一季度    130
二季度    390
三季度    260
四季度    370
dtype: int64
'''

#向量運算
#我們嘗試把ser1和ser2對應季度的資料加起來,程式碼如下所示。
ser3 = ser1 + ser2
print(ser3, '\n')
'''
一季度    450
二季度    770
三季度    510
四季度    730
dtype: int64
'''

#索引運算
#跟陣列一樣,Series物件也可以進行索引和切片操作,不同的是Series物件因為內部維護了一個儲存索引的陣列
#所以除了可以使用整數索引檢索資料外,還可以透過自己設定的索引(標籤)獲取對應的資料。

#使用整數索引
print(ser1[2])  #260
#使用自定義索引。
print(ser1['三季度'])  #260

#賦值
ser1['一季度'] = 100
print(ser1)
'''
一季度    100
二季度    390
三季度    260
四季度    370
dtype: int64
'''

print('---------------------------------------------')

#切片索引
#Series物件的切片操作跟列表、陣列類似,透過給出起始和結束索引,從原來的Series物件中取出或修改部分資料
# 這裡也可以使用整數索引和自定義的索引
print(ser2[1:3], '\n')    #[1:3] 表示從索引為1(包含)到索引為3(不包含)的資料
'''
二季度    380
三季度    250
dtype: int64
'''

#提示:在使用自定義索引進行切片時,結束索引對應的元素也是可以取到的。
print(ser2['二季度':'三季度'], '\n')
'''
二季度    380
三季度    250
dtype: int64
'''

#修改
ser2[1:3] = 400, 500
print(ser2, '\n')
'''
一季度    320
二季度    400
三季度    500
四季度    360
dtype: int64 
'''
print('---------------------------------------------')

#花式索引
#取值
print(ser2[['二季度', '四季度']], '\n') # = ser2['二季度':'四季度']
'''
二季度    400
四季度    360
dtype: int64
'''

#修改值
ser2[['二季度', '四季度']] = 600, 520
print(ser2, '\n')
'''
一季度    320
二季度    600
三季度    500
四季度    520
dtype: int64
'''
print('---------------------------------------------')

#布林索引
print(ser2[ser2 >= 500])
'''
二季度    600
三季度    500
四季度    520
dtype: int64
'''

Series 物件的屬性和方法

Series物件的屬性和方法非常多,看下面的表格,它展示了Series物件常用的屬性。

屬性 說明
dtype / dtypes 返回Series物件的資料型別
hasnans 判斷Series物件中有沒有空值
at / iat 透過索引訪問Series物件中的單個值
loc / iloc 透過索引訪問Series物件中的單個值或一組值
index 返回Series物件的索引(Index物件)
is_monotonic 判斷Series物件中的資料是否單調
is_monotonic_increasing 判斷Series物件中的資料是否單調遞增
is_monotonic_decreasing 判斷Series物件中的資料是否單調遞減
is_unique 判斷Series物件中的資料是否獨一無二
size 返回Series物件中元素的個數
values ndarray的方式返回Series物件中的值(ndarray物件

我們可以透過下面的程式碼來了解Series物件的屬性。

#Series物件的屬性和方法
print(ser2.dtype)   #資料型別
print(ser2.hasnans) #判斷有無空值
print(ser2.index)   #索引
print(ser2.values)  #值
print(ser2.is_monotonic_increasing) #判斷索引是否是單調遞增
print(ser2.is_unique)   #判斷索引是否唯一
'''
int64
False
Index(['一季度', '二季度', '三季度', '四季度'], dtype='object')
[320 600 500 520]
False
True
'''

print('----------------------------------------------')

#統計相關
#Series物件支援各種獲取描述性統計資訊的方法。
print(ser2.count()) #統計非空值的個數
print(ser2.sum())   #統計所有值的和
print(ser2.mean())  #統計所有值的平均值
print(ser2.median())    #統計所有值的中位數
print(ser2.max())
print(ser2.min())
print(ser2.std())       #統計所有值的標準差
print(ser2.var())   #統計所有值的方差
'''
4
1940
485.0
510.0
600
320
118.18065267490557
13966.666666666666
'''
print('----------------------------------------------')

#Series物件還有一個名為describe()的方法,可以獲得上述所有的描述性統計資訊
print(ser2.describe())

'''
count      4.000000
mean     485.000000
std      118.180653
min      320.000000
25%      455.000000
50%      510.000000
75%      540.000000
max      600.000000
dtype: float64
'''
#提示:因為describe()返回的也是一個Series物件
#所以也可以用ser2.describe()['mean']來獲取平均值,用ser2.describe()[['max', 'min']]來獲取最大值和最小值。
print(ser2.describe()['mean'])

print('----------------------------------------------')
#統計重複項
#如果Series物件有重複的值,我們可以使用unique()方法獲得由獨一無二的值構成的陣列;
# 可以使用nunique()方法統計不重複值的數量;如果想要統計每個值重複的次數,可以使用value_counts()方法,這個方法會返回一個Series物件,
# 它的索引就是原來的Series物件中的值,而每個值出現的次數就是返回的Series物件中的資料,在預設情況下會按照出現次數做降序排列,如下所示

#value_counts:統計重複項
ser3 = pandas.Series(data=['apple', 'banana', 'pitaya', 'apple', 'pitaya', 'durian'])
print(ser3.value_counts())
'''
apple     2
pitaya    2
banana    1
durian    1
Name: count, dtype: int64
'''

#nunique(): 統計不重複值、不重複值數量
print(ser3.nunique())   #4

#對於ser3,我們還可以用mode()方法來找出資料的眾數,由於眾數可能不唯一,所以mode()方法的返回值仍然是一個Series物件。
print(ser3.mode())
'''
0     apple
1    pitaya
dtype: object
'''


print('----------------------------------------------')

#處理資料
#Series物件的isna()和isnull()方法可以用於空值的判斷,notna()和notnull()方法可以用於非空值的判斷,程式碼如下所示。
ser4 = pandas.Series(data=[10, 20, numpy.nan, 30, numpy.nan])
print(ser4.isna())
'''
0    False
1    False
2     True
3    False
4     True
dtype: bool
'''
#說明:np.nan是一個IEEE 754標準的浮點小數,專門用來表示“不是一個數”
# 在上面的程式碼中我們用它來代表空值;當然,也可以用 Python 中的None來表示空值,在 pandas 中None也會被處理為np.nan

#判斷非空值
print(ser4.notna())
'''
0     True
1     True
2    False
3     True
4    False
dtype: bool
'''

print('----------------------------------------------')

#Series物件的dropna()和fillna()方法分別用來刪除空值和填充空值,具體的用法如下所示。

#刪除空值
print(ser4.dropna())
'''
0    10.0
1    20.0
3    30.0
dtype: float64
'''

#填充空值
print(ser4.fillna(value=40))    #填充值為40
'''
0    10.0
1    20.0
2    40.0
3    30.0
4    40.0
dtype: float64
'''
#需要提醒大家注意的是,dropna()和fillna()方法都有一個名為inplace的引數,
# 它的預設值是False,表示刪除空值或填充空值不會修改原來的Series物件,而是返回一個新的Series物件。
# 如果將inplace引數的值修改為True,那麼刪除或填充空值會就地操作,直接修改原來的Series物件,此時方法的返回值是None。
# 後面我們會接觸到的很多方法,包括DataFrame物件的很多方法都會有這個引數,它們的意義跟這裡是一樣的。

print('----------------------------------------------')
#Series物件的mask()和where()方法可以將滿足或不滿足條件的值進行替換,如下所示。

#和where()方法
ser5 = pandas.Series(range(5))
print(ser5.where(ser5 > 0))
print(ser5.where(ser5 > 1, 10))

#mask()方法
print(ser5.mask(ser5 > 1, 10))
print('----------------------------------------------')

#Series物件的duplicated()方法可以幫助我們找出重複的資料,而drop_duplicates()方法可以幫我們刪除重複資料。
# print(ser3)
print(ser3.duplicated())    #找出重複資料
print(ser3.drop_duplicates())   #刪除重複資料

print('----------------------------------------------')

#Series物件的apply()和map()方法非常重要,它們可以透過字典或者指定的函式來處理資料,把資料對映或轉換成我們想要的樣子。
# 這兩個方法在資料準備階段非常重要,我們先來試一試這個名為map的方法。

ser6 = pandas.Series(['cat', 'dog', numpy.nan, 'rabbit'])
# print(ser6)

# map()方法
#說明:透過字典給出的對映規則對資料進行處理。
# map()方法返回一個新的Series物件,而不是修改原來的Series物件。
print(ser6.map({'cat': 'kitten', 'dog': 'puppy'}))
'''
0       I am a cat
1       I am a dog
2              NaN
3    I am a rabbit
dtype: object
'''

#說明:將指定字串的format方法作用到資料系列的資料上,忽略掉所有的空值。
print(ser6.map('I am a {}'.format, na_action='ignore'))
'''
0          I am a cat
1          I am a dog
2    I am a numpy.nan
3       I am a rabbit
dtype: object
'''

print('----------------------------------------------')

#apply()
ser7 = pandas.Series([20, 21, 12],  index=['London', 'New York', 'Helsinki'])
# print(ser7)

#說明:將求平方的函式作用到資料系列的資料上,也可以將引數np.square替換為lambda x: x ** 2。
print(ser7.apply(numpy.square))
'''
London      400
New York    441
Helsinki    144
dtype: int64
'''

#注意:apply方法中的lambda函式有兩個引數,第一個引數是資料系列中的資料,而第二個引數需要我們傳入,
# 所以我們給apply方法增加了args引數,用於給lambda函式的第二個引數傳值。
print(ser7.apply(lambda x, value: x - value, args=(5, )))
'''
London      15
New York    16
Helsinki     7
dtype: int64
'''
print('----------------------------------------------')

#取頭部值和排序
#Series物件的sort_index()和sort_values()方法可以用於對索引和資料的排序,排序方法有一個名為ascending的布林型別引數,
# 該引數用於控制排序的結果是升序還是降序;而名為kind的引數則用來控制排序使用的演算法,
# 預設使用了quicksort,也可以選擇mergesort或heapsort;
# 如果存在空值,那麼可以用na_position引數空值放在最前還是最後,預設是last,程式碼如下所示
ser8 = pandas.Series(
    data=[35, 96, 12, 57, 25, 89],
    index=['grape', 'banana', 'pitaya', 'apple', 'peach', 'orange']
)
print(ser8.sort_values())   #按值從小到大排序
'''
pitaya    12
peach     25
grape     35
apple     57
orange    89
banana    96
dtype: int64
'''
print(ser8.sort_index(ascending=False)) ## 按索引從大到小排序 ascending: True 升序,False 降序
print('----------------------------------------------')

#如果要從Series物件中找出元素中最大或最小的“Top-N”,我們不需要對所有的值進行排序的,
# 可以使用nlargest()和nsmallest()方法來完成
print(ser8.nlargest(3)) #找出3個最大值
'''
banana    96
orange    89
apple     57
dtype: int64
'''

#找出2個最小的值
print(ser8.nsmallest(2))
'''
pitaya    12
peach     25
dtype: int64
'''

繪製圖表

Series物件有一個名為plot的方法可以用來生成圖表,如果選擇生成折線圖、餅圖、柱狀圖等,預設會使用Series物件的索引作為橫座標,使用Series物件的資料作為縱座標

# -*- coding: utf-8 -*-
#繪製圖表""

import numpy
import pandas
import matplotlib.pyplot as plt

#建立Series物件
ser9 = pandas.Series({'Q1': 400, 'Q2': 520, 'Q3': 600, 'Q4': 800})
#透過plot方法的kind指定圖表型別位柱狀圖
ser9.plot(kind='bar')
#定製縱軸的取值範圍
plt.ylim(0, 1000)
#定製橫軸刻度(旋轉到0度)
plt.xticks(rotation=0)
#為柱子新增資料標籤
#ser9.size獲取柱子的個數
print(range(ser9.size)) #range(0, 4)
for i in range(ser9.size):
    #獲取柱子的位置和長度
    #plt.text(x, y, text, ha='center')
    plt.text(i, ser9[i] + 5, ser9[i], ha='center')
    print(i, ser9[i] + 5, ser9[i])

#顯示
plt.show()

python-資料分析-Pandas-1、Series物件

繪製餅圖

#繪製餅圖
import numpy
import pandas
import matplotlib.pyplot as plt

#建立Series物件
ser9 = pandas.Series({'Q1': 400, 'Q2': 520, 'Q3': 600, 'Q4': 800})
# plot方法的kind引數指定了圖表型別為餅圖
# autopct會自動計算並顯示百分比
# pctdistance用來控制百分比到圓心的距離
ser9.plot(kind='pie', autopct='%1.1f%%', pctdistance=0.65)
#顯示
plt.show()

python-資料分析-Pandas-1、Series物件

相關文章