Pandas數據分析的基礎知識入門

andas是基於Numpy構建的含有更高級數據結構和工具的數據分析包。類似於Numpy的核心是ndarray,pandas 也是圍繞著 Series 和 DataFrame兩個核心數據結構展開的。Series 和 DataFrame 分別對應於一維的序列和二維的表結構。

Pandas數據分析的基礎知識入門

Pandas數據分析的基礎知識入門

Pandas官方教程User Guide ,查看當前版本:

>>> import pandas as pd

>>> import numpy as np

>>> print(pd.__version__)

1.0.1

文件讀取與寫入

1、文件讀取

>>> df = pd.read_csv('data/table.csv') # csv格式

>>> df_txt = pd.read_table('data/table.txt') # txt格式

>>> df_excel = pd.read_excel('data/table.xlsx') #xls或xlsx格式,需要安裝xlrd包

2、寫入文件

>>> df.to_csv('data/new_table.csv') # csv格式

>>> df.to_csv('data/new_table.csv', index=False) # 保存時除去行索引

>>> df.to_excel('data/new_table2.xlsx', sheet_name='Sheet1') # xls或xlsx格式,需要安裝openpyxl

基本數據結構

1、Series

一種類似於一維數組的對象,是由一組數據(各種NumPy數據類型)以及一組與之相關的數據標籤(即索引)組成。僅由一組數據也可產生簡單的Series對象。注意:Series中的索引值是可以重複的。

A. 創建Series

對於一個Series,其中最常用的屬性為值(values),索引(index),名字(name),類型(dtype)。

>>> s = pd.Series(np.random.randn(5),index=['a','b','c','d','e'],name='Series Sample',dtype='float64')

>>> print(s)

a -0.509401

b -0.684058

c -0.759703

d 0.089692

e -0.114861

Name: Series Sample, dtype: float64

B. 訪問Series屬性

>>> s.values

array([-0.50940132, -0.68405815, -0.75970341, 0.08969204, -0.11486061])

>>> s.index

Index(['a', 'b', 'c', 'd', 'e'], dtype='object')

>>> s.name

'Series Sample'

>>> s.dtype

dtype('float64')

C. 索引元素

>>> s['a']

-0.5094013170899359

D. 調用方法Series有相當多的方法可以調用:

>>> print([attr for attr in dir(s) if not attr.startswith('_')])

['T', 'a', 'abs', 'add', 'add_prefix', 'add_suffix', 'agg', 'aggregate', 'align', 'all', 'any', 'append', 'apply', 'argmax', 'argmin', 'argsort', 'array', 'asfreq', 'asof', 'astype', 'at', 'at_time', 'attrs', 'autocorr', 'axes', 'b', 'between', 'between_time', 'bfill', 'bool', 'c', 'clip', 'combine', 'combine_first', 'convert_dtypes', 'copy', 'corr', 'count', 'cov', 'cummax', 'cummin', 'cumprod', 'cumsum', 'd', 'describe', 'diff', 'div', 'divide', 'divmod', 'dot', 'drop', 'drop_duplicates', 'droplevel', 'dropna', 'dtype', 'dtypes', 'duplicated', 'e', 'empty', 'eq', 'equals', 'ewm', 'expanding', 'explode', 'factorize', 'ffill', 'fillna', 'filter', 'first', 'first_valid_index', 'floordiv', 'ge', 'get', 'groupby', 'gt', 'hasnans', 'head', 'hist', 'iat', 'idxmax', 'idxmin', 'iloc', 'index', 'infer_objects', 'interpolate', 'is_monotonic', 'is_monotonic_decreasing', 'is_monotonic_increasing', 'is_unique', 'isin', 'isna', 'isnull', 'item', 'items', 'iteritems', 'keys', 'kurt', 'kurtosis', 'last', 'last_valid_index', 'le', 'loc', 'lt', 'mad', 'map', 'mask', 'max', 'mean', 'median', 'memory_usage', 'min', 'mod', 'mode', 'mul', 'multiply', 'name', 'nbytes', 'ndim', 'ne', 'nlargest', 'notna', 'notnull', 'nsmallest', 'nunique', 'pct_change', 'pipe', 'plot', 'pop', 'pow', 'prod', 'product', 'quantile', 'radd', 'rank', 'ravel', 'rdiv', 'rdivmod', 'reindex', 'reindex_like', 'rename', 'rename_axis', 'reorder_levels', 'repeat', 'replace', 'resample', 'reset_index', 'rfloordiv', 'rmod', 'rmul', 'rolling', 'round', 'rpow', 'rsub', 'rtruediv', 'sample', 'searchsorted', 'sem', 'set_axis', 'shape', 'shift', 'size', 'skew', 'slice_shift', 'sort_index', 'sort_values', 'squeeze', 'std', 'sub', 'subtract', 'sum', 'swapaxes', 'swaplevel', 'tail', 'take', 'to_clipboard', 'to_csv', 'to_dict', 'to_excel', 'to_frame', 'to_hdf', 'to_json', 'to_latex', 'to_list', 'to_markdown', 'to_numpy', 'to_period', 'to_pickle', 'to_sql', 'to_string', 'to_timestamp', 'to_xarray', 'transform', 'transpose', 'truediv', 'truncate', 'tshift', 'tz_convert', 'tz_localize', 'unique', 'unstack', 'update', 'value_counts', 'values', 'var', 'view', 'where', 'xs']

>>> s.mean()
-0.3956662892383938

2、DataFrame

一個表格型的數據結構,包含有一組有序的列,每列可以是不同的值類型(數值、字符串、布爾型等),DataFrame即有行索引也有列索引,可以被看做是由Series組成的字典。

A. 創建DataFrame

>>> df = pd.DataFrame({'col1':list('abcde'),'col2':range(5,10),'col3':[1.3,2.5,3.6,4.6,5.8]},

index=list('一二三四五'))

>>> df

col1 col2 col3

一 a 5 1.3

二 b 6 2.5

三 c 7 3.6

四 d 8 4.6

五 e 9 5.8

B. 從DataFrame取出一列為Series

>>> df['col1']

一 a

二 b

三 c

四 d

五 e

Name: col1, dtype: object

>>> type(df)

pandas.core.frame.DataFrame

>>> type(df['col1'])

pandas.core.series.Series

C. 修改行或列名

>>> df.rename(index={'一':'one'},columns={'col1':'new_col1'})

new_col1 col2 col3

one a 5 1.3

二 b 6 2.5

三 c 7 3.6

四 d 8 4.6

五 e 9 5.8

D. 調用屬性和方法

>>> df.index

Index(['一', '二', '三', '四', '五'], dtype='object')

>>> df.columns

Index(['col1', 'col2', 'col3'], dtype='object')

>>> df.values

array([['a', 5, 1.3],

['b', 6, 2.5],

['c', 7, 3.6],

['d', 8, 4.6],

['e', 9, 5.8]], dtype=object)

>>> df.shape

(5, 3)

>>> df.mean() #本質上是一種Aggregation操作

col2 7.00

col3 3.56

dtype: float64

E. 索引對齊特

這是Pandas中非常強大的特性,不理解這一特性有時就會造成一些麻煩。

>>> df1 = pd.DataFrame({'A':[1,2,3]},index=[1,2,3])

>>> df2 = pd.DataFrame({'A':[1,2,3]},index=[3,1,2])

>>> df1-df2 #由於索引對齊,因此結果不是0

A

1 -1

2 -1

3 2

F. 列的刪除與添加對於刪除而言,可以使用drop函數或del或pop。

>>> df.drop(index='五',columns='col1') #設置inplace=True後會直接在原DataFrame中改動

col2 col3

一 5 1.3

二 6 2.5

三 7 3.6

四 8 4.6

>>> df['col1']=[1,2,3,4,5] #增加col1列

>>> del df['col2']

>>> df

col3 col1

一 1.3 1

二 2.5 2

三 3.6 3

四 4.6 4

五 5.8 5

pop方法直接在原來的DataFrame上操作,且返回被刪除的列,與python中的pop函數類似。

>>> df['col1']=[1,2,3,4,5]

>>> df.pop('col1')

一 1

二 2

三 3

四 4

五 5

Name: col1, dtype: int64

>>> df

col2 col3

一 5 1.3

二 6 2.5

三 7 3.6

四 8 4.6

五 9 5.8

可以直接增加新的列,也可以使用assign方法。

>>> df1['B']=list('abc')

>>> df1

A B

1 1 a

2 2 b

3 3 c

>>> df1.assign(C=pd.Series(list('def'))) # 索引對齊
A B C
1 1 a e
2 2 b f
3 3 c NaN
# 但assign方法不會對原DataFrame做修改
>>> df1
A B
1 1 a
2 2 b
3 3 c

G. 根據類型選擇列

>>> df.select_dtypes(include=['number']).head()

col2 col3

一 5 1.3

二 6 2.5

三 7 3.6

四 8 4.6

五 9 5.8

>>> df.select_dtypes(include=['float']).head()

col3

一 1.3

二 2.5

三 3.6

四 4.6

五 5.8

H. 將Series轉換為DataFrame

>>> s = df.mean()

>>> s.name='to_DataFrame'

>>> s # pandas.core.series.Series

col2 7.00

col3 3.56

Name: to_DataFrame, dtype: float64

>>> s.to_frame()

to_DataFrame

col2 7.00

col3 3.56

>>> s.to_frame().T # 使用T符號可以轉置

col2 col3

to_DataFrame 7.0 3.56

常用基本函數

df = pd.read_csv('data/table.csv')

1. head和tail

>>> df.head() # 顯示前幾行

>>> df.tail() # 顯示後幾行

>>> df.head(3).append(df.tail(3))

School Class ID Gender Address Height Weight Math Physics

0 S_1 C_1 1101 M street_1 173 63 34.0 A+

1 S_1 C_1 1102 F street_2 192 73 32.5 B+

2 S_1 C_1 1103 M street_2 186 82 87.2 B+

32 S_2 C_4 2403 F street_6 158 60 59.7 B+

33 S_2 C_4 2404 F street_2 160 84 67.7 B

34 S_2 C_4 2405 F street_6 193 54 47.6 B

2. unique和nunique

# nunique顯示有多少個唯一值。

>>> df['Physics'].nunique()

7

# unique顯示所有的唯一值

>>> df['Physics'].unique()

array(['A+', 'B+', 'B-', 'A-', 'B', 'A', 'C'], dtype=object)

3. count和value_counts

# count返回非缺失值元素個數

>>> df['Physics'].count()

35

# value_counts返回每個元素有多少個

>>> df['Physics'].value_counts()

B+ 9

B 8

B- 6

A 4

A+ 3

A- 3

C 2

Name: Physics, dtype: int64

4. describe和info

# describe默認統計數值型數據的各個統計量

>>> df.describe()

ID Height Weight Math

count 35.00000 35.000000 35.000000 35.000000

mean 1803.00000 174.142857 74.657143 61.351429

std 536.87741 13.541098 12.895377 19.915164

min 1101.00000 155.000000 53.000000 31.500000

25% 1204.50000 161.000000 63.000000 47.400000

50% 2103.00000 173.000000 74.000000 61.700000

75% 2301.50000 187.500000 82.000000 77.100000

max 2405.00000 195.000000 100.000000 97.000000

# 可以自行選擇分位數

>>> df.describe(percentiles=[.05, .25, .75, .95])

# 對於非數值型也可以用describe函數

>>> df['Physics'].describe()

count 35

unique 7

top B+

freq 9

Name: Physics, dtype: object

info函數返回有哪些列、有多少非缺失值、每列的類型。

>>> df.info()

RangeIndex: 35 entries, 0 to 34

Data columns (total 9 columns):

# Column Non-Null Count Dtype

--- ------ -------------- -----

0 School 35 non-null object

1 Class 35 non-null object

2 ID 35 non-null int64

3 Gender 35 non-null object

4 Address 35 non-null object

5 Height 35 non-null int64

6 Weight 35 non-null int64

7 Math 35 non-null float64

8 Physics 35 non-null object

dtypes: float64(1), int64(3), object(5)

memory usage: 2.6+ KB

5. idxmax和nlargest

# idxmax函數返回最大值的索引,在某些情況下特別適用,idxmin功能類似

>>> df['Math'].idxmax()

5

# nlargest函數返回前幾個大的元素值,nsmallest功能類似

>>> df['Math'].nlargest(3)

5 97.0

28 95.5

11 87.7

Name: Math, dtype: float64

6. clip和replaceclip和replace是兩類替換函數,clip是對超過或者低於某些值的數進行截斷。

>>> df['Math'].head()

0 34.0

1 32.5

2 87.2

3 80.4

4 84.8

Name: Math, dtype: float64

>>> df['Math'].clip(33,80).head()

0 34.0

1 33.0

2 80.0

3 80.0

4 80.0

Name: Math, dtype: float64

replace是對某些值進行替換。

>>> df['Address'].head()

0 street_1

1 street_2

2 street_2

3 street_2

4 street_4

Name: Address, dtype: object

>>> df['Address'].replace(['street_1','street_2'],['one','two']).head()

0 one

1 two

2 two

3 two

4 street_4

Name: Address, dtype: object

# 通過字典,可以直接在表中修改

>>> df.replace({'Address':{'street_1':'one','street_2':'two'}}).head()

7. apply函數apply是一個自由度很高的函數,對於Series,它可以迭代每一列的值操作。對於DataFrame,它可以迭代每一個列操作:

>>> df['Math'].apply(lambda x:str(x)+'!').head() #可以使用lambda表達式,也可以使用函數

0 34.0!

1 32.5!

2 87.2!

3 80.4!

4 84.8!

Name: Math, dtype: object

>>> df.apply(lambda x:x.apply(lambda x:str(x)+'!')).head() #這是一個稍顯複雜的例子,有利於理解apply的功能

School Class ID Gender Address Height Weight Math Physics

0 S_1! C_1! 1101! M! street_1! 173! 63! 34.0! A+!

1 S_1! C_1! 1102! F! street_2! 192! 73! 32.5! B+!

2 S_1! C_1! 1103! M! street_2! 186! 82! 87.2! B+!

3 S_1! C_1! 1104! F! street_2! 167! 81! 80.4! B-!

4 S_1! C_1! 1105! F! street_4! 159! 64! 84.8! B+!

排序

A. 索引排序

>>> df.set_index('Math').head() #set_index函數可以設置索引
>>> df.set_index('Math').sort_index().head() #可以設置ascending參數,默認為升序,True
School Class ID Gender Address Height Weight Physics
Math
31.5 S_1 C_3 1301 M street_4 161 68 B+


32.5 S_1 C_1 1102 F street_2 192 73 B+
32.7 S_2 C_3 2302 M street_5 171 88 A
33.8 S_1 C_2 1204 F street_5 162 63 B
34.0 S_1 C_1 1101 M street_1 173 63 A+

B. 值排序

>>> df.sort_values(by='Class').head()

# 多個值排序,即先對第一層排,在第一層相同的情況下對第二層排序

>>> df.sort_values(by=['Address','Height']).head()

問題與練習

1. 問題

【問題一】 Series和DataFrame有哪些常見屬性和方法?

【問題二】 value_counts會統計缺失值嗎?

【問題三】 與idxmax和nlargest功能相反的是哪兩組函數?

【問題四】 在常用函數一節中,由於一些函數的功能比較簡單,因此沒有列入,現在將它們列在下面,請分別說明它們的用途並嘗試使用。 sum/mean/median/mad/min/max/abs/std/var/quantile/cummax/cumsum/cumprod

【問題五】 df.mean(axis=1)是什麼意思?它與df.mean()的結果一樣嗎?第一問提到的函數也有axis參數嗎?怎麼使用?

2. 練習

【練習一】 現有一份關於美劇《權力的遊戲》劇本的數據集,請解決以下問題:

(a)在所有的數據中,一共出現了多少人物?

(b)以單元格計數(即簡單把一個單元格視作一句),誰說了最多的話?

(c)以單詞計數,誰說了最多的單詞?

Pandas數據分析的基礎知識入門

# 參考答案

# 問題a

>>> pd.read_csv('data/Game_of_Thrones_Script.csv').head()

>>> df["Name"].nunique() # 564

# 問題b

>>> df.groupby("Name")["words"].sum().idxmax()

'tyrion lannister'

# 問題c

>>> df = df.assign(words = df["Sentence"].apply(lambda x:len(x.split()))).sort_values(by="Name")

>>> df.assign(Words = df["Sentence"].apply(lambda x:len(x.split()))).groupby("Name")["words"].sum().idxmax()

'tyrion lannister'

【練習二】現有一份關於科比的投籃數據集,請解決如下問題:(a)哪種action_type和combined_shot_type的組合是最多的?(b)在所有被記錄的game_id中,遭遇到最多的opponent是一個支?

>>> df = pd.read_csv('data/Kobe_data.csv',index_col='shot_id')

>>> df.head()

Pandas數據分析的基礎知識入門

# 問題a

>>> df = df[["action_type","combined_shot_type"]]

>>> df.groupby("action_type")["combined_shot_type"].value_counts().sort_values(ascending=False)

action_type combined_shot_type

Jump Shot Jump Shot 18880

Layup Shot Layup 2567

Driving Layup Shot Layup 1978

Turnaround Jump Shot Jump Shot 1057

Fadeaway Jump Shot Jump Shot 1048

Running Jump Shot Jump Shot 926

Pullup Jump shot Jump Shot 476

# 問題b

>>> df = pd.read_csv('data/Kobe_data.csv',index_col='shot_id').iloc[:,[3,-1]]

>>> pd.Series(list(list(zip(*(pd.Series(list(zip(df["game_id"],df["opponent"]))).unique()).tolist()))[1])).value_counts().index[0]

'SAS'



分享到:


相關文章: