在前面一篇文章中,我們對(duì)pandas做了一些入門介紹。本文是它的進(jìn)階篇。在這篇文章中,我們會(huì)講解一些更深入的知識(shí)。 前言本文緊接著前一篇的入門教程,會(huì)介紹一些關(guān)于pandas的進(jìn)階知識(shí)。建議讀者在閱讀本文之前先看完pandas入門教程。 同樣的,本文的測(cè)試數(shù)據(jù)和源碼可以在這里獲取: Github:pandas_tutorial 。 數(shù)據(jù)訪問在入門教程中,我們已經(jīng)使用過訪問數(shù)據(jù)的方法。這里我們?cè)偌锌匆幌隆?/p>
基礎(chǔ)方法: |
1 2 3 4 5 6 7 8 9 10 11 | # select_data.py import pandas as pd import numpy as np series1 = pd.Series([1, 2, 3, 4, 5, 6, 7], index=['C', 'D', 'E', 'F', 'G', 'A', 'B']) print('series1['E'] = {} \n'.format(series1['E'])); print('series1.E = {} \n'.format(series1.E)); |
這段代碼輸出如下:
1 2 3 4 | series1['E'] = 3 series1.E = 3 |
注1:對(duì)于類似屬性的訪問方式
.
來說,要求索引元素必須是有效的Python標(biāo)識(shí)符的時(shí)候才可以,而對(duì)于series1.1
這樣的索引是不行的。
注2:
[]
和.
提供了簡單和快速訪問pands數(shù)據(jù)結(jié)構(gòu)的方法。這種方法非常的直觀。然而,由于要訪問的數(shù)據(jù)類型并不是事先知道的,因此使用這兩種方法方式存在一些優(yōu)化限制。因此對(duì)于產(chǎn)品級(jí)的代碼來說,pandas官方建議使用pandas庫中提供的數(shù)據(jù)訪問方法。
在入門教程中,我們已經(jīng)提到了這兩個(gè)操作符:
loc
:通過行和列的索引來訪問數(shù)據(jù)
iloc
:通過行和列的下標(biāo)來訪問數(shù)據(jù)
注意:索引的類型可能是整數(shù)。
實(shí)際上,當(dāng)DataFrame
通過這兩個(gè)操作符訪問數(shù)據(jù),可以只指定一個(gè)索引來訪問一行的數(shù)據(jù),例如:
1 2 3 4 5 6 7 | # select_data.py df1 = pd.DataFrame({'note' : ['C', 'D', 'E', 'F', 'G', 'A', 'B'], 'weekday': ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']}, index=['1', '2', '3', '4', '5', '6', '7']) print('df1.loc['2']:\n{}\n'.format(df1.loc['2'])) |
這里通過索引'2'
可以方法到第2行的所有數(shù)據(jù),因此它的輸出如下:
1 2 3 4 5 | df1.loc['2']: note D weekday Tue Name: 2, dtype: object |
除此之外,通過這兩個(gè)操作符我們還可以訪問某個(gè)范圍之內(nèi)的數(shù)據(jù),例如這樣:
1 2 3 4 5 | # select_data.py print('series1.loc['E':'A']=\n{}\n'.format(series1.loc['E':'A'])); print('df1.iloc[2:4]=\n{}\n'.format(df1.iloc[2:4])) |
這段代碼輸出如下:
1 2 3 4 5 6 7 8 9 10 11 12 | series1.loc['E':'A']= E 3 F 4 G 5 A 6 dtype: int64 df1.iloc[2:3]= note weekday 3 E Wed 4 F Thu |
這兩個(gè)操作符用來訪問單個(gè)的元素值(Scalar Value)。類似的:
at
:通過行和列的索引來訪問數(shù)據(jù)
iat
:通過行和列的下標(biāo)來訪問數(shù)據(jù)
1 2 3 4 5 | # select_data.py print('series1.at['E']={}\n'.format(series1.at['E'])); print('df1.iloc[4,1]={}\n'.format(df1.iloc[4,1])) |
這兩行代碼輸出如下:
1 2 3 4 | series1.at['E']=3 df1.iloc[4,1]=Fri |
在入門教程我們也已經(jīng)簡單介紹過Index,Index提供了查找,數(shù)據(jù)對(duì)齊和重新索引所需的基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)。 最直接的,我們可以通過一個(gè)數(shù)組來創(chuàng)建Index對(duì)象。在創(chuàng)建的同時(shí)我們還可以通過name
指定索引的名稱:
1 2 3 4 | # index.py index = pd.Index(['C','D','E','F','G','A','B'], name='note') |
Index類提供了很多的方法進(jìn)行各種操作,這個(gè)建議讀者直接查詢API說明即可,這里不多做說明。稍微提一下的是,Index對(duì)象可以互相之間做集合操作,例如:
1 2 3 4 5 6 7 8 9 | # index.py a = pd.Index([1,2,3,4,5]) b = pd.Index([3,4,5,6,7]) print('a|b = {}\n'.format(a|b)) print('a&b = {}\n'.format(a&b)) print('a.difference(b) = {}\n'.format(a.difference(b))) |
這幾個(gè)運(yùn)算的結(jié)果如下:
1 2 3 4 5 6 | a|b = Int64Index([1, 2, 3, 4, 5, 6, 7], dtype='int64') a&b = Int64Index([3, 4, 5], dtype='int64') a.difference(b) = Int64Index([1, 2], dtype='int64') |
Index類有很多的子類,下面是最常見的一些:
MultiIndex,或者稱之為Hierarchical Index是指數(shù)據(jù)的行或者列通過多層次的標(biāo)簽來進(jìn)行索引。 例如,我們要通過一個(gè)MultiIndex描述三個(gè)公司在三年內(nèi)每個(gè)季度的營業(yè)額,可以這樣:
1 2 3 4 5 6 7 8 9 10 11 12 | # multiindex.py import pandas as pd import numpy as np multiIndex = pd.MultiIndex.from_arrays([ ['Geagle', 'Geagle', 'Geagle', 'Geagle', 'Epple', 'Epple', 'Epple', 'Epple', 'Macrosoft', 'Macrosoft', 'Macrosoft', 'Macrosoft', ], ['S1', 'S2', 'S3', 'S4', 'S1', 'S2', 'S3', 'S4', 'S1', 'S2', 'S3', 'S4']], names=('Company', 'Turnover')) |
這段代碼輸出如下:
1 2 3 4 5 | multiIndex = MultiIndex(levels=[['Epple', 'Geagle', 'Macrosoft'], ['S1', 'S2', 'S3', 'S4']], labels=[[1, 1, 1, 1, 0, 0, 0, 0, 2, 2, 2, 2], [0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3]], names=['Company', 'Turnover']) |
從這個(gè)輸出可以看出,MultiIndex中的levels
數(shù)組數(shù)量對(duì)應(yīng)了索引的級(jí)別數(shù)量,labels
對(duì)應(yīng)了levels
中元素的下標(biāo)。 下面我們用一個(gè)隨機(jī)數(shù)來構(gòu)造一個(gè)DataFrame:
1 2 3 4 5 6 7 | # multiindex.py df = pd.DataFrame(data=np.random.randint(0, 1000, 36).reshape(-1, 12), index=[2016, 2017, 2018], columns=multiIndex) print('df = \n{}\n'.format(df)) |
這里創(chuàng)建出了36個(gè)[0, 1000)
之間的隨機(jī)數(shù),然后組裝成3行12列的矩陣(如果你對(duì)NumPy不熟悉可以訪問NumPy官網(wǎng)學(xué)習(xí),或者看一下我之前寫過的:Python 機(jī)器學(xué)習(xí)庫 NumPy 教程)。 上面這段代碼輸出如下:
1 2 3 4 5 6 7 | df = Company Geagle Epple Macrosoft Turnover S1 S2 S3 S4 S1 S2 S3 S4 S1 S2 S3 S4 2016 329 25 553 852 833 710 247 990 215 991 535 846 2017 734 368 28 161 187 444 901 858 244 915 261 485 2018 769 707 458 782 948 169 927 237 279 438 738 708 |
這個(gè)輸出很直觀的可以看出三個(gè)公司在三年內(nèi)每個(gè)季度的營業(yè)額。 有了多級(jí)索引,我們可以方便的進(jìn)行數(shù)據(jù)的篩選,例如:
通過df.loc[2017, (['Geagle', 'Epple', 'Macrosoft'] ,'S1')])
篩選出三個(gè)公司2017年第一季度的營業(yè)額
通過df.loc[2018, 'Geagle']
篩選出Geagle公司2018年每個(gè)季度的營業(yè)額
它們輸出如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 2017 S1: Company Turnover Geagle S1 734 Epple S1 187 Macrosoft S1 244 Name: 2017, dtype: int64 Geagle 2018: Turnover S1 769 S2 707 S3 458 S4 782 Name: 2018, dtype: int64 |
Concat(enate):串聯(lián),連接,級(jí)連
Append:附加,增補(bǔ)
Merge:融合,歸并,合并
Join:合并,接合,交接
concat
函數(shù)的作用是將多個(gè)數(shù)據(jù)串聯(lián)到一起。例如,某個(gè)多條數(shù)據(jù)分散在3個(gè)地方記錄,最后我們將三個(gè)數(shù)據(jù)添加到一起。下面是一個(gè)代碼示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | # concat_append.py import pandas as pd import numpy as np df1 = pd.DataFrame({'Note': ['C', 'D'], 'Weekday': ['Mon', 'Tue']}, index=[1, 2]) df2 = pd.DataFrame({'Note': ['E', 'F'], 'Weekday': ['Wed', 'Thu']}, index=[3, 4]) df3 = pd.DataFrame({'Note': ['G', 'A', 'B'], 'Weekday': ['Fri', 'Sat', 'Sun']}, index=[5, 6, 7]) df_concat = pd.concat([df1, df2, df3], keys=['df1', 'df2', 'df3']) print('df_concat=\n{}\n'.format(df_concat)) |
這里我們通過keys
指定了三個(gè)數(shù)據(jù)的索引劃分,最后的數(shù)據(jù)中會(huì)由此存在MultiIndex。這段代碼輸出如下:
1 2 3 4 5 6 7 8 9 10 | df_concat= Note Weekday df1 1 C Mon 2 D Tue df2 3 E Wed 4 F Thu df3 5 G Fri 6 A Sat 7 B Sun |
請(qǐng)仔細(xì)思考一下df_concat
結(jié)構(gòu)與原先三個(gè)數(shù)據(jù)結(jié)構(gòu)的關(guān)系:其實(shí)它就是將原先三個(gè)數(shù)據(jù)縱向串聯(lián)起來了。另外,請(qǐng)關(guān)注一下MultiIndex結(jié)構(gòu)。 concat
函數(shù)默認(rèn)是以axis=0
(行)為主進(jìn)行串聯(lián)。如果需要,我們可以指定axis=1
(列)為主進(jìn)行串聯(lián):
1 2 3 4 5 | # concat_append.py df_concat_column = pd.concat([df1, df2, df3], axis=1) print('df_concat_column=\n{}\n'.format(df_concat_column)) |
這個(gè)結(jié)構(gòu)輸出如下:
1 2 3 4 5 6 7 8 9 10 | df_concat_column= Note Weekday Note Weekday Note Weekday 1 C Mon NaN NaN NaN NaN 2 D Tue NaN NaN NaN NaN 3 NaN NaN E Wed NaN NaN 4 NaN NaN F Thu NaN NaN 5 NaN NaN NaN NaN G Fri 6 NaN NaN NaN NaN A Sat 7 NaN NaN NaN NaN B Sun |
請(qǐng)?jiān)俅斡^察一下這里的結(jié)果和原先三個(gè)數(shù)據(jù)結(jié)構(gòu)之間的關(guān)系。 concat
是將多個(gè)數(shù)據(jù)串聯(lián)在一起。類似的,對(duì)于某個(gè)具體的數(shù)據(jù)來說,我們可以在其數(shù)據(jù)基礎(chǔ)上添加(append)其他數(shù)據(jù)來進(jìn)行串聯(lián):
1 2 3 4 5 | # concat_append.py df_append = df1.append([df2, df3]) print('df_append=\n{}\n'.format(df_append)) |
這個(gè)操作的結(jié)果和之前的concat
是一樣的:
1 2 3 4 5 6 7 8 9 10 | df_append= Note Weekday 1 C Mon 2 D Tue 3 E Wed 4 F Thu 5 G Fri 6 A Sat 7 B Sun |
pandas中的Merge操作和SQL語句中的Join操作是類似的。Join操作可以分為下面幾種:
INNER
LEFT OUTER
RIGHT OUTER
FULL OUTER
CROSS
關(guān)于這幾種的Join操作的含義請(qǐng)參閱其他資料,例如維基百科:Join (SQL)。 使用pandas進(jìn)行Merge操作很簡單,下面是一段代碼示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | # merge_join.py import pandas as pd import numpy as np df1 = pd.DataFrame({'key': ['K1', 'K2', 'K3', 'K4'], 'A': ['A1', 'A2', 'A3', 'A8'], 'B': ['B1', 'B2', 'B3', 'B8']}) df2 = pd.DataFrame({'key': ['K3', 'K4', 'K5', 'K6'], 'A': ['A3', 'A4', 'A5', 'A6'], 'B': ['B3', 'B4', 'B5', 'B6']}) print('df1=n{}n'.format(df1)) print('df2=n{}n'.format(df2)) merge_df = pd.merge(df1, df2) merge_inner = pd.merge(df1, df2, how='inner', on=['key']) merge_left = pd.merge(df1, df2, how='left') merge_left_on_key = pd.merge(df1, df2, how='left', on=['key']) merge_right_on_key = pd.merge(df1, df2, how='right', on=['key']) merge_outer = pd.merge(df1, df2, how='outer', on=['key']) print('merge_df=\n{}\n'.format(merge_df)) print('merge_inner=\n{}\n'.format(merge_inner)) print('merge_left=\n{}\n'.format(merge_left)) print('merge_left_on_key=\n{}\n'.format(merge_left_on_key)) print('merge_right_on_key=\n{}\n'.format(merge_right_on_key)) print('merge_outer=\n{}\n'.format(merge_outer)) |
這段代碼說明如下:
merge
函數(shù)的join
參數(shù)的默認(rèn)值是“inner”,因此merge_df是兩個(gè)數(shù)據(jù)的inner join
的結(jié)果。另外,在不指明的情況下,merge
函數(shù)使用所有同名的列名作為key來進(jìn)行運(yùn)算。
merge_inner是指定了列的名稱進(jìn)行inner join
。
merge_left是left outer join
的結(jié)果
merge_left_on_key是指定了列名進(jìn)行left outer join
的結(jié)果
merge_right_on_key是指定了列名進(jìn)行right outer join
的結(jié)果
merge_outer是full outer join
的結(jié)果
這里的結(jié)果如下,請(qǐng)觀察一下結(jié)果與你的預(yù)算是否一致:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | df1= A B key 0 A1 B1 K1 1 A2 B2 K2 2 A3 B3 K3 3 A8 B8 K4 df2= A B key 0 A3 B3 K3 1 A4 B4 K4 2 A5 B5 K5 3 A6 B6 K6 merge_df= A B key 0 A3 B3 K3 merge_inner= A_x B_x key A_y B_y 0 A3 B3 K3 A3 B3 1 A8 B8 K4 A4 B4 merge_left= A B key 0 A1 B1 K1 1 A2 B2 K2 2 A3 B3 K3 3 A8 B8 K4 merge_left_on_key= A_x B_x key A_y B_y 0 A1 B1 K1 NaN NaN 1 A2 B2 K2 NaN NaN 2 A3 B3 K3 A3 B3 3 A8 B8 K4 A4 B4 merge_right_on_key= A_x B_x key A_y B_y 0 A3 B3 K3 A3 B3 1 A8 B8 K4 A4 B4 2 NaN NaN K5 A5 B5 3 NaN NaN K6 A6 B6 merge_outer= A_x B_x key A_y B_y 0 A1 B1 K1 NaN NaN 1 A2 B2 K2 NaN NaN 2 A3 B3 K3 A3 B3 3 A8 B8 K4 A4 B4 4 NaN NaN K5 A5 B5 5 NaN NaN K6 A6 B6 |
DataFrame也提供了join
函數(shù)來根據(jù)索引進(jìn)行數(shù)據(jù)合并。它可以被用于合并多個(gè)DataFrame,這些DataFrame有相同的或者類似的索引,但是沒有重復(fù)的列名。默認(rèn)情況下,join
函數(shù)執(zhí)行left join
。另外,假設(shè)兩個(gè)數(shù)據(jù)有相同的列名,我們可以通過lsuffix
和rsuffix
來指定結(jié)果中列名的前綴。下面是一段代碼示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | # merge_join.py df3 = pd.DataFrame({'key': ['K1', 'K2', 'K3', 'K4'], 'A': ['A1', 'A2', 'A3', 'A8'], 'B': ['B1', 'B2', 'B3', 'B8']}, index=[0, 1, 2, 3]) df4 = pd.DataFrame({'key': ['K3', 'K4', 'K5', 'K6'], 'C': ['A3', 'A4', 'A5', 'A6'], 'D': ['B3', 'B4', 'B5', 'B6']}, index=[1, 2, 3, 4]) print('df3=\n{}\n'.format(df3)) print('df4=\n{}\n'.format(df4)) join_df = df3.join(df4, lsuffix='_self', rsuffix='_other') join_left = df3.join(df4, how='left', lsuffix='_self', rsuffix='_other') join_right = df1.join(df4, how='outer', lsuffix='_self', rsuffix='_other') print('join_df=\n{}\n'.format(join_df)) print('join_left=\n{}\n'.format(join_left)) print('join_right=\n{}\n'.format(join_right)) |
這段代碼輸出如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | df3= A B key 0 A1 B1 K1 1 A2 B2 K2 2 A3 B3 K3 3 A8 B8 K4 df4= C D key 1 A3 B3 K3 2 A4 B4 K4 3 A5 B5 K5 4 A6 B6 K6 join_df= A B key_self C D key_other 0 A1 B1 K1 NaN NaN NaN 1 A2 B2 K2 A3 B3 K3 2 A3 B3 K3 A4 B4 K4 3 A8 B8 K4 A5 B5 K5 join_left= A B key_self C D key_other 0 A1 B1 K1 NaN NaN NaN 1 A2 B2 K2 A3 B3 K3 2 A3 B3 K3 A4 B4 K4 3 A8 B8 K4 A5 B5 K5 join_right= A B key_self C D key_other 0 A1 B1 K1 NaN NaN NaN 1 A2 B2 K2 A3 B3 K3 2 A3 B3 K3 A4 B4 K4 3 A8 B8 K4 A5 B5 K5 4 NaN NaN NaN A6 B6 K6 |
很多時(shí)候,我們會(huì)需要對(duì)批量的數(shù)據(jù)進(jìn)行分組統(tǒng)計(jì)或者再處理,groupby
,agg
,apply
就是用來做這件事的。
groupby
將數(shù)據(jù)分組,分組后得到pandas.core.groupby.DataFrameGroupBy
類型的數(shù)據(jù)。
agg
用來進(jìn)行合計(jì)操作,agg
是aggregate
的別名。
apply
用來將函數(shù)func分組化并將結(jié)果組合在一起。
這些概念都很抽象,我們還是通過代碼來進(jìn)行說明。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | # groupby.py import pandas as pd import numpy as np df = pd.DataFrame({ 'Name': ['A','A','A','B','B','B','C','C','C'], 'Data': np.random.randint(0, 100, 9)}) print('df=\n{}\n'.format(df)) groupby = df.groupby('Name') print('Print GroupBy:') for name, group in groupby: print('Name: {}\nGroup:\n{}\n'.format(name, group)) |
在這段代碼中,我們生成了9個(gè)[0, 100)之間的隨機(jī)數(shù),數(shù)據(jù)的第一列是['A','A','A','B','B','B','C','C','C']
。然后我們以Name
列進(jìn)行groupby
,得到的結(jié)果會(huì)根據(jù)將Name
列值一樣的分組在一起,我們將得到的結(jié)果進(jìn)行了打印。這段代碼的輸出如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | df= Data Name 0 34 A 1 44 A 2 57 A 3 81 B 4 78 B 5 65 B 6 73 C 7 16 C 8 1 C Print GroupBy: Name: A Group: Data Name 0 34 A 1 44 A 2 57 A Name: B Group: Data Name 3 81 B 4 78 B 5 65 B Name: C Group: Data Name 6 73 C 7 16 C 8 1 C |
groupby
并不是我們的最終目的,我們的目的是希望分組后還要對(duì)這些數(shù)據(jù)進(jìn)行進(jìn)一步的統(tǒng)計(jì)或者處理。pandas庫本身就提供了很多進(jìn)行操作的函數(shù),例如:count,sum,mean,median,std,var,min,max,prod,first,last
。這些函數(shù)的名稱很容易明白它的作用。 例如:groupby.sum()
就是對(duì)結(jié)果進(jìn)行求和運(yùn)行。 除了直接調(diào)用這些函數(shù)之外,我們也可以通過agg
函數(shù)來達(dá)到這個(gè)目的,這個(gè)函數(shù)接收其他函數(shù)的名稱,例如這樣:groupby.agg(['sum'])
。 通過agg
函數(shù),可以一次性調(diào)用多個(gè)函數(shù),并且可以為結(jié)果列指定名稱。 像這樣:groupby.agg([('Total', 'sum'), ('Min', 'min')])
。 這里的三個(gè)調(diào)用輸出結(jié)果如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # groupby.py Sum: Data Name A 135 B 224 C 90 Agg Sum: Data sum Name A 135 B 224 C 90 Agg Map: Data Total Min Name A 135 34 B 224 65 C 90 1 |
除了對(duì)數(shù)據(jù)集合進(jìn)行統(tǒng)計(jì),我們也可以通過apply
函數(shù)進(jìn)行分組數(shù)據(jù)的處理。像這樣:
1 2 3 4 5 6 7 | # groupby.py def sort(df): return df.sort_values(by='Data', ascending=False) print('Sort Group: \n{}\n'.format(groupby.apply(sort))) |
在這段代碼中,我們定義了一個(gè)排序函數(shù),并應(yīng)用在分組數(shù)據(jù)上,這里最終的輸出如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 | Sort Group: Data Name A 2 57 1 44 0 34 B 3 81 4 78 5 65 C 6 73 7 16 8 1 |
時(shí)間是應(yīng)用程序中很頻繁需要處理的邏輯,尤其是對(duì)于金融,科技,商業(yè)等領(lǐng)域。 當(dāng)我們?cè)谟懻摃r(shí)間,我們討論的可能是下面三種情況中的一種:
某個(gè)具體的時(shí)間點(diǎn)(Timestamp),例如:今天下午一點(diǎn)整
某個(gè)時(shí)間范圍(Period),例如:整個(gè)這個(gè)月
某個(gè)時(shí)間間隔(Interval),例如:每周二上午七點(diǎn)整
Python語言提供了時(shí)間日期相關(guān)的基本API,它們位于datetime
, time
, calendar
幾個(gè)模塊中。下面是一個(gè)代碼示例:
1 2 3 4 5 6 7 8 9 10 11 12 | # time.py import datetime as dt import numpy as np import pandas as pd now = dt.datetime.now(); print('Now is {}'.format(now)) yesterday = now - dt.timedelta(1); print('Yesterday is {}\n'.format(yesterday.strftime('%Y-%m-%d'))) |
在這段代碼中,我們打印了今天的日期,并通過timedelta
進(jìn)行了日期的減法運(yùn)算。這段代碼輸出如下: 借助pandas提供的接口,我們可以很方便的獲得以某個(gè)時(shí)間間隔的時(shí)間序列,例如這樣:
1 2 3 4 5 6 | # time.py this_year = pd.date_range(dt.datetime(2018, 1, 1), dt.datetime(2018, 12, 31), freq='5D') print('Selected days in 2018: \n{}\n'.format(this_year)) |
這段代碼獲取了整個(gè)2018年中從元旦開始,每隔5天的日期序列。 date_range
函數(shù)的詳細(xì)說明見這里:pandas.date_range 這段代碼的輸出如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | Selected days in 2018: DatetimeIndex(['2018-01-01', '2018-01-06', '2018-01-11', '2018-01-16', '2018-01-21', '2018-01-26', '2018-01-31', '2018-02-05', '2018-02-10', '2018-02-15', '2018-02-20', '2018-02-25', '2018-03-02', '2018-03-07', '2018-03-12', '2018-03-17', '2018-03-22', '2018-03-27', '2018-04-01', '2018-04-06', '2018-04-11', '2018-04-16', '2018-04-21', '2018-04-26', '2018-05-01', '2018-05-06', '2018-05-11', '2018-05-16', '2018-05-21', '2018-05-26', '2018-05-31', '2018-06-05', '2018-06-10', '2018-06-15', '2018-06-20', '2018-06-25', '2018-06-30', '2018-07-05', '2018-07-10', '2018-07-15', '2018-07-20', '2018-07-25', '2018-07-30', '2018-08-04', '2018-08-09', '2018-08-14', '2018-08-19', '2018-08-24', '2018-08-29', '2018-09-03', '2018-09-08', '2018-09-13', '2018-09-18', '2018-09-23', '2018-09-28', '2018-10-03', '2018-10-08', '2018-10-13', '2018-10-18', '2018-10-23', '2018-10-28', '2018-11-02', '2018-11-07', '2018-11-12', '2018-11-17', '2018-11-22', '2018-11-27', '2018-12-02', '2018-12-07', '2018-12-12', '2018-12-17', '2018-12-22', '2018-12-27'], dtype='datetime64[ns]', freq='5D') |
我們得到的返回值是DatetimeIndex
類型的,我們可以創(chuàng)建一個(gè)DataFrame并以此作為索引:
1 2 3 4 5 | # time.py df = pd.DataFrame(np.random.randint(0, 100, this_year.size), index=this_year) print('Jan: \n{}\n'.format(df['2018-01'])) |
在這段代碼中,我們創(chuàng)建了與索引數(shù)量一樣多的[0, 100)間的隨機(jī)整數(shù),并用this_year
作為索引。用DatetimeIndex
作索引的好處是,我們可以直接指定某個(gè)范圍來選擇數(shù)據(jù),例如,通過df['2018-01']
選出所有1月份的數(shù)據(jù)。 這段代碼輸出如下:
1 2 3 4 5 6 7 8 9 10 | Jan: 0 2018-01-01 61 2018-01-06 85 2018-01-11 66 2018-01-16 11 2018-01-21 34 2018-01-26 2 2018-01-31 97 |
pandas的圖形展示依賴于matplotlib
庫。對(duì)于這個(gè)庫,我們?cè)诤竺鏁?huì)專門講解,因?yàn)檫@里僅僅提供一個(gè)簡單的代碼示例,讓大家感受一下圖形展示的樣子。 代碼示例如下:
1 2 3 4 5 6 7 8 9 | # plot.py import matplotlib.pyplot as plt import pandas as pd data = pd.read_csv('data/housing.csv') data.hist(bins=50, figsize=(15, 12)) plt.show() |
這段代碼讀取了一個(gè)CSV文件,這個(gè)文件中包含了一些關(guān)于房價(jià)的信息。在讀取完之后,通過直方圖(hist)將其展示了出來。 該CSV文件的內(nèi)容見這里:pandas_tutorial/data/housing.csv 直方圖結(jié)果如下所示:
雖然本文的標(biāo)題是“進(jìn)階篇”,我們也討論了一些更深入的知識(shí)。但很顯然,這對(duì)于pandas來說,仍然是很皮毛的東西。由于篇幅所限,更多的內(nèi)容在今后的時(shí)候,有機(jī)會(huì)我們?cè)賮硪黄鹛接憽?讀者朋友也可以根據(jù)官網(wǎng)上的文檔進(jìn)行更深入的學(xué)習(xí)。
|