Pandas與Matplotlib基礎


pandas是Python中開源的,高性能的用於數據分析的庫。其中包含了很多可用的數據結構及功能,各種結構支持相互轉換,並且支持讀取、保存數據。結合matplotlib庫,可以將數據已圖表的形式可視化,反映出數據的各項特征。
先借用一張圖來描述一下pandas的一些基本使用方法,下面會通過一些實例對這些知識點進行應用。
 

 

一、安裝pandas庫
pandas庫不屬於Python自帶的庫,所以需要單獨下載,如果已經安裝了Python,可以使用pip工具下載pandas:
pip install pandas
如果還未安裝Python的話,推薦使用Anaconda,一款集成了Python及其一系列用於數據分析、科學計算的專用包的平台,省去了單獨安裝各個庫的麻煩(內置Python版本為3.6)。
 

 

二、pandas的基本數據結構
1.Seris
Seris是一維的,帶索引的數組,支持多種數據類型。可以使用列表進行轉換:
s = pd.Series([3, -5, 7, 4], index=['a', 'b', 'c', 'd'])
print(s)
 
# result
a    3
b   -5
c    7
d    4
dtype: int64
也可以重新指定索引:
s.index = ['A', 'B', 'C', 'D']
print(s)

# result
A    3
B   -5
C    7
D    4
dtype: int64
 
2.DataFrame
一種二維的,類似於Excel表格的數據結構,可以為其指定列名、索引名。
將字典結構轉換為DataFrame:
data = {
    'Country': ['Belgium', 'India', 'Brazil'],
    'Capital': ['Brussels', 'New Delhi', 'Brasília'],
    'Population': [11190846, 1303171035, 207847528]
}
df = pd.DataFrame(data, columns=['Country', 'Capital', 'Population'])
print(df)
 
# result
   Country    Capital  Population
0  Belgium   Brussels    11190846
1    India  New Delhi  1303171035
2   Brazil   Brasília   207847528

 

三、基本操作
1.查看DataFrame數據的基本信息:
對已一個剛接觸的數據集,最好的了解它的方式就是先通過一些簡單的命令查看他的基本結構,比如有多少行、多少列,列名是什么,是否有索引等等。pandas提供了這樣的一系列命令讓我們能夠輕松的進行查詢(以下部分實例使用此數據集)。
1) 查看行列信息:
print(df.shape)

# result
(260, 218)
說明df包含260行,218列數據。
 
2) 查看列名及索引名:
print(df.columns)
print(df.index)
 
# result
Index(['Life expectancy', '1800', '1801', '1802', '1803', '1804', '1805',
       '1806', '1807', '1808',
       ...
       '2007', '2008', '2009', '2010', '2011', '2012', '2013', '2014', '2015',
       '2016'],
      dtype='object', length=218)
 
Int64Index([  0,   1,   2,   3,   4,   5,   6,   7,   8,   9,
            ...
            250, 251, 252, 253, 254, 255, 256, 257, 258, 259],
           dtype='int64', length=260)
 
3) 查看描述該DataFrame的基本信息:
print(df.info())

# result
<class 'pandas.core.frame.DataFrame'>
Int64Index: 260 entries, 0 to 259
Columns: 218 entries, Life expectancy to 2016
dtypes: float64(217), object(1)
memory usage: 444.8+ KB
可以看出df.info()顯示的信息較全面,對索引、列、數據類型都做出了描述。
 
4) 查看開頭/結尾幾行的數據:
對數據的基本情況了解后,有時候我們可能還想看一下具體的數據,從而有一個更加全面的認識,可以使用head(), tail()方法查看DataFrame的前幾行/后幾行數據。
print(df.head())

# result
         Life expectancy   1800   1801   1802   1803   1804   1805   1806  \
0               Abkhazia    NaN    NaN    NaN    NaN    NaN    NaN    NaN   
1            Afghanistan  28.21  28.20  28.19  28.18  28.17  28.16  28.15   
2  Akrotiri and Dhekelia    NaN    NaN    NaN    NaN    NaN    NaN    NaN   
3                Albania  35.40  35.40  35.40  35.40  35.40  35.40  35.40   
4                Algeria  28.82  28.82  28.82  28.82  28.82  28.82  28.82   
 
    1807   1808  ...        2016  
0    NaN    NaN  ...    0    NaN  
1  28.14  28.13  ...    1  52.72  
2    NaN    NaN  ...    2    NaN  
3  35.40  35.40  ...    3  78.10  
4  28.82  28.82  ...    4  76.50  
 
[5 rows x 218 columns]

 

print(df.tail())

# result
    Life expectancy   1800   1801   1802   1803   1804   1805   1806   1807  \
255      Yugoslavia    NaN    NaN    NaN    NaN    NaN    NaN    NaN    NaN   
256          Zambia  32.60  32.60  32.60  32.60  32.60  32.60  32.60  32.60   
257        Zimbabwe  33.70  33.70  33.70  33.70  33.70  33.70  33.70  33.70   
258           ?land    NaN    NaN    NaN    NaN    NaN    NaN    NaN    NaN   
259     South Sudan  26.67  26.67  26.67  26.67  26.67  26.67  26.67  26.67   
 
      1808  ...     2016  
255    NaN  ...      NaN  
256  32.60  ...    57.10  
257  33.70  ...    61.69  
258    NaN  ...      NaN  
259  26.67  ...    56.10  
 
[5 rows x 218 columns] 
我使用的這個數據集的列有點多,所以python使用了"\"進行換行,並使用省略號省去了大部分的列數據,使其不必顯示所有的列。
 
2.從DataFrame中選擇子集:
對於一個較龐大的數據集,我們有時候只想對其中的一部分數據進行分析,那么我們就需要用合適的方法從中取出。pandas支持使用多種方式對數據進行選取:
1) 根據列名選擇:
selected_cols = ['2010', '2011', '2012']
date_df = df[selected_cols]
print(date_df.head())
 
# result
   2010  2011  2012
0   NaN   NaN   NaN
1  53.6  54.0  54.4
2   NaN   NaN   NaN
3  77.2  77.4  77.5
4  76.0  76.1  76.2

 

2) 根據標簽選擇:
使用loc[]方法通過指定列名、索引名來獲得相應的數據集。以我上面使用的df數據為例,取第250行的'Life expectancy'列的數據:
print(df.loc[250, 'Life expectancy'])
 
# result
250                  Vietnam
 
Name: Life expectancy, dtype: object

 

3) 根據位置選擇:
使用iloc[]通過指定列名、索引名對應的索引位置(從0到n-1)獲取數據(可以使用slice分片方式表示)。如果我想取前十行中最后兩列的數據,應該這樣表示:
df.iloc[:10, -2:]
 
# result
   2015   2016
0   NaN    NaN
1  53.8  52.72
2   NaN    NaN
3  78.0  78.10
4  76.4  76.50
5  72.9  73.00
6  84.8  84.80
7  59.6  60.00
8   NaN    NaN
9  76.4  76.50
注:iloc[]中的slice分片方式與列表的分片方式相同,都不包含最后一位。例如上面的df.iloc[:10, -2:]值包含0~9行,而不包含第10行數據。
 
4) 布爾索引(Boolean Indexing)
也叫做布爾掩碼(Boolean mask),是指先根據條件對DataFrame進行運算,生成一個值為True/False的DataFrame,再通過此DF與原DF進行匹配,得到符合條件的DF。
mask = df > 50
print(df[mask].head())

#result
         Life expectancy  1800  1801  1802  1803  1804  1805  1806  1807  \
0               Abkhazia   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   
1            Afghanistan   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   
2  Akrotiri and Dhekelia   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   
3                Albania   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   
4                Algeria   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   
 
   1808  ...    2007  2008  2009  2010  2011  2012  2013  2014  2015   2016  
0   NaN  ...     NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN    NaN  
1   NaN  ...    52.4  52.8  53.3  53.6  54.0  54.4  54.8  54.9  53.8  52.72  
2   NaN  ...     NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN   NaN    NaN  
3   NaN  ...    76.6  76.8  77.0  77.2  77.4  77.5  77.7  77.9  78.0  78.10  
4   NaN  ...    75.3  75.5  75.7  76.0  76.1  76.2  76.3  76.3  76.4  76.50  
 
[5 rows x 218 columns]
不符合條件的顯示為NaN。
 
3.Broadcasting
通過將某一列的值刷成固定的值。例如對一些身高數據做轉換時,添加一列'SEX'列,並統一將值更新為'MALE':
heights = [59.0, 65.2, 62.9, 65.4, 63.7]
data = {
    'height': heights, 'sex': 'Male',
}
df_heights = pd.DataFrame(data)
print(df_heights)
 
# result
   height   sex
0    59.0  Male
1    65.2  Male
2    62.9  Male
3    65.4  Male
4    63.7  Male

 

4.設置列名及索引名:
如果需要重新指定列名或索引名,可直接通過df.columns(),df.index()指定。
df_heights.columns = ['HEIGHT', 'SEX']
df_heights.index = ['david', 'bob', 'lily', 'sara', 'tim']
print(df_heights)
 
# result
       HEIGHT   SEX
david    59.0  Male
bob      65.2  Male
lily     62.9  Male
sara     65.4  Male
tim      63.7  Male

 

5.使用聚合函數
如果需要對數據進行一些統計,可使用聚合函數進行計算。
1) df.sum()
將所有值按列加到一起:
print(df_heights.sum())
 
# result
HEIGHT                   316.2
SEX       MaleMaleMaleMaleMale
dtype: object
字符串sum后會合並在一起。
 
2) df.cumsum()
統計累積加和值:
print(df_heights.cumsum())
 
# result
      HEIGHT                   SEX
david     59                  Male
bob    124.2              MaleMale
lily   187.1          MaleMaleMale
sara   252.5      MaleMaleMaleMale
tim    316.2  MaleMaleMaleMaleMale
 
3) df.max() / df.min()
求最大/最小值
print(df_heights.max())

# result
HEIGHT    65.4
SEX       Male
dtype: object

 

print(df_heights.min())

# result
HEIGHT      59
SEX       Male
dtype: object
注: df.idxmax() / df.idxmin() 方法可得極值對應的索引值。
 
4) df.mean()
求平均數
print(df_heights.mean())
 
# result
HEIGHT    63.24
dtype: float64
數據類型為字符串的列會被自動過濾。
 
5) df.median()
求中位數
print(df_heights.median())
 
# result
HEIGHT    63.7
dtype: float64

 

6) df.describe()
獲取DF的基本統計信息:
print(df_heights.describe())
 
# result
          HEIGHT
count   5.000000
mean   63.240000
std     2.589015
min    59.000000
25%    62.900000
50%    63.700000
75%    65.200000
max    65.400000

 

6.從DataFrame中刪除數據
1) 通過指定行索引刪除行數據:
df_heights.drop(['david', 'tim'])
print(df_heights)
# result
       HEIGHT   SEX
david    59.0  Male
bob      65.2  Male
lily     62.9  Male
sara     65.4  Male
tim      63.7  Male
 我們發現drop'david', 'tim'所在行后, 再次打印df_height,之前刪除的兩行數據還在。說明drop()方法不會直接對原有的DF進行操作,如果需要改變原DF,需要進行賦值:
df_heights = df_heights.drop(['david', 'tim'])
print(df_heights)

# result
      HEIGHT   SEX
bob     65.2  Male
lily    62.9  Male
sara    65.4  Male

 

2) 通過指定列值刪除列數據(需指定axis=1):
print(df_heights.drop('SEX', axis=1))

# result
HEIGHT
david 177.0
bob 195.6
lily 188.7
sara 196.2
tim 191.1
同樣,如果需要改變原DF,需要重新賦值。
 
7.排序
1) 根據索引值進行排序:
print(df_heights.sort_index())
 
# result
       HEIGHT   SEX
bob      65.2  Male
david    59.0  Male
lily     62.9  Male
sara     65.4  Male
tim      63.7  Male

 

2) 根據值進行排序(需指定列名):
print(df_heights.sort_values(by='HEIGHT'))
 
# result
       HEIGHT   SEX
david    59.0  Male
lily     62.9  Male
tim      63.7  Male
bob      65.2  Male
sara     65.4  Male

 

8.排名
根據列值進行排名:
print(df_heights.rank())
 
# result
       HEIGHT  SEX
david     1.0  3.0
bob       4.0  3.0
lily      2.0  3.0
sara      5.0  3.0
tim       3.0  3.0

 

9.使用lambda函數:
例如,對df_heights中的身高列進行轉換(inch -> cm):
df_heights = df_heights.apply(lambda height: height*3)
print(df_heights)
 
# result
       HEIGHT           SEX
david   177.0  MaleMaleMale
bob     195.6  MaleMaleMale
lily    188.7  MaleMaleMale
sara    196.2  MaleMaleMale
tim     191.1  MaleMaleMale

 

四、csv文件的導入導出
1.csv導入(數據集):
df = pd.read_csv("tips.csv")
print(df.info())
 
# result
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 244 entries, 0 to 243
Data columns (total 8 columns):
total_bill    244 non-null float64
tip           244 non-null float64
sex           244 non-null object
smoker        244 non-null object
day           244 non-null object
time          244 non-null object
size          244 non-null int64
fraction      244 non-null float64
dtypes: float64(3), int64(1), object(4)
memory usage: 15.3+ KB 
 
2.pd.read_csv()的一些常用選項
header=None: 不導入column
names: 指定column
df = pd.read_csv('tips.csv', header=None, names=column_names)

 

na_values: 將NaN替換成指定字符
df = pd.read_csv('tips.csv', header=None, names=column_names, na_values={'DAY': '-1'})

 

parse_dates:合並表示時間的列
date_df = pd.read_csv('created_date.csv', parse_dates=[[3, 4, 5]])

 

五、保存CSV文件
支持保存為csv格式及excel格式的文件:
date_df.to_csv('tips1.csv')
date_df.to_csv('tips2.csv', sep='|')     # 分隔符為'|'
date_df.to_excel('tips3.xlsx')
 
六、配合Matplotlib繪制簡單圖表
Matplotlib庫是python的一個2D圖形庫,可以生成多種高質量的圖形,通過各種不同類型的圖形體現數據的價值。
1.繪制折線圖:
折線圖一般用於反映數據在一段時間內的變化情況。我們先導入一份數據(Percentage of bachelor's degrees awarded to women in the USA),這個數據集描述了從1970~2011年,美國女性在各個專業的學士學位獲取比例的情況:
 

 

雖然數據比較全,但是僅僅從這個表格上去對比各個專業之間的差異還是有些困難的,這時我們就可以通過使用matplotlib畫圖表的方式展示這些數據之間的關系。
1) 引入pandas庫后先導入數據:
import pandas as pd
import matplotlib.pyplot as plt
 
 
df = pd.read_csv('percent-bachelors-degrees-women-usa.csv', index_col='Year')
print(df.info())
print(df.head())
 
# result
      Agriculture  Architecture  Art and Performance    Biology   Business  \ ... ...         Social Sciences and History  
Year                                                                          ... ...   Year                               
1970     4.229798     11.921005                 59.7  29.088363   9.064439    ... ...   1970                         36.8  
1971     5.452797     12.003106                 59.9  29.394403   9.503187    ... ...   1971                         36.2  
1972     7.420710     13.214594                 60.4  29.810221  10.558962    ... ...   1972                         36.1  
1973     9.653602     14.791613                 60.2  31.147915  12.804602    ... ...   1973                         36.4  
1974    14.074623     17.444688                 61.9  32.996183  16.204850    ... ...   1974                         37.3  
 
 
<class 'pandas.core.frame.DataFrame'>
Int64Index: 42 entries, 1970 to 2011
Data columns (total 17 columns):
Agriculture                      42 non-null float64
Architecture                     42 non-null float64
Art and Performance              42 non-null float64
Biology                          42 non-null float64
Business                         42 non-null float64
Communications and Journalism    42 non-null float64
Computer Science                 42 non-null float64
Education                        42 non-null float64
Engineering                      42 non-null float64
English                          42 non-null float64
Foreign Languages                42 non-null float64
Health Professions               42 non-null float64
Math and Statistics              42 non-null float64
Physical Sciences                42 non-null float64
Psychology                       42 non-null float64
Public Administration            42 non-null float64
Social Sciences and History      42 non-null float64
dtypes: float64(17)
memory usage: 5.9 KB
可以看出,'Year'為索引列,這次數據統計一共包含了17個專業。
 
2) 繪圖
可以使用matplotlib.pyplot中的plt()方法進行繪圖。我們先試着分析某一列的數據,看一下具體是如何展示的:
df_CS = df['Computer Science']
plt.plot(df_CS)
plt.show()
從圖中我們看到,索引值作為X軸的刻度展示,Y軸則表示這一列的具體數值。從這個圖中可以直觀的看出這段時間學位的獲取情況。
 
3) 添加標題和標簽
僅僅這樣展示似乎有些單調,matplotlib還提供了一系列可供自定義的功能:
df_CS = df['Computer Science']
plt.plot(df_CS)
# 為圖表添加標題
plt.title("Percentage of Computer Science's degrees awarded to women in the USA")
# 為X軸添加標簽
plt.xlabel("Years")
# 為Y軸添加標簽
plt.ylabel("Percentage")
plt.show()

 

添加了標題和標簽,就好看一些了。
 
4) 繪制多個圖形進行對比
如果我們想看Math and Statistics與Computer Science的差異,可以一並繪出並展示:
df_CS = df['Computer Science']
df_MS = df['Math and Statistics']
# 可以通過DataFrame的plot()方法直接繪制
# color指定線條的顏色
# style指定線條的樣式
# legend指定是否使用標識區分
df_CS.plot(color='b', style='.-', legend=True)
df_MS.plot(color='r', style='-', legend=True)
plt.title("Percentage of Computer Science's degrees VS Math and Statistics's")
plt.xlabel("Years")
plt.ylabel("Percentage")
plt.show()

可以看出Math and Statistics明顯高於Computer Science。
 
最后,我們繪制所有數據的曲線:
# alpha指定透明度(0~1)
df.plot(alpha=0.7)
plt.title("Percentage of bachelor's degrees awarded to women in the USA")
plt.xlabel("Years")
plt.ylabel("Percentage")
# axis指定X軸Y軸的取值范圍
plt.axis((1970, 2000, 0, 200))
plt.show()

 

5) 保存圖像
使用plt.savefig()保存圖像,支持PNG, JPG,PDF等格式。
plt.savefig('percent-bachelors.png')
plt.savefig('percent-bachelors.jpg')
plt.savefig('percent-bachelors.pdf')
 
2.其他類型的圖像
除了折線圖,matplob還支持繪制散點圖等其他類型,只需要在調用plot()畫圖之前指定kind參數即可。
1) 散點圖
散點圖可以體現數據在一定范圍內的分布情況。上述數據集不適合畫散點圖,所以我們重新導入一份著名的鳶尾花數據(在數據分析和機器學習中經常被用到)。
我們在導入數據后,分析sepal(萼片)的長度和寬度數據:
iris = pd.read_csv("iris.csv")
# 源數據中沒有給column,所以需要手動指定一下
iris.columns = ['sepal_length', 'sepal_width', 'petal_length', 'petal_width', 'species']
# kind表示圖形的類型
# x, y 分別指定X, Y 軸所指定的數據
iris.plot(kind='scatter', x='sepal_length', y='sepal_width')
plt.xlabel("sepal length in cm")
plt.ylabel("sepal width in cm")
plt.title("iris data analysis")
plt.show()

 

從散點圖可以看出,數據主要集中在中間靠下的這部分區域(如果使用折線圖,就是這些點連起來的折線,將變得雜亂無章)。
 
2) box箱圖
box箱圖也可以體現數據的分布情況,與散點圖不同的是,它還統計了最大/最小值、中位數的值,一目了然:
iris.plot(kind='box', y='sepal_length')
plt.ylabel("sepal length in cm")
plt.show()

 

3) Histogram柱狀圖
柱狀圖體現了數據的分布情況及出現的頻率,將數據展示得更加直觀。下面我們從數據集中取出類別為"Iris-setosa"的子集,並使用柱狀圖統計它的四類數據:
# 使用mask取出子集
mask = (iris.species == 'Iris-setosa')
setosa = iris[mask]
# bins指定柱狀圖的個數
# range指定X軸的取值范圍
setosa.plot(kind='hist', bins=50, range=(0, 8), alpha=0.5)
plt.title("setosa in iris")
plt.xlabel("CM")
plt.show()

 

 
Pandas與Matplotlib中常用的內容就給大家介紹到這了。這兩種工具非常容易上手,但是想要精通,真正用好也需要花些心思。后面有機會再寫一些較深入的文章吧 : )


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM