pandas使用指南:初學(xué)者向(上)

pandas 使用指南(上)

pandas作為一種可以提供類似于R中dataframe數(shù)據(jù)結(jié)構(gòu)的module對(duì)于經(jīng)常進(jìn)行機(jī)器學(xué)習(xí)和數(shù)據(jù)處理的同學(xué)是一種非常高效的數(shù)據(jù)結(jié)構(gòu)工具伞访。Pandas上面已經(jīng)提供了一份簡(jiǎn)易指南铸题,但是全文太長(zhǎng)了(雖然其標(biāo)榜十分鐘內(nèi)可以學(xué)會(huì)),故而決定寫一份旨在給剛剛開始使用pandas的初學(xué)者的簡(jiǎn)化版潦匈,因此如果讀者已經(jīng)有一定的pandas使用經(jīng)驗(yàn)的話粘勒,可以略過本文。

本文的主要內(nèi)容包括:

  • 解釋?dataframe的基本結(jié)構(gòu)
  • 幾種常見的創(chuàng)建dataframe的方法
  • 幾種常用的獲得dataframe中數(shù)據(jù)的方法
  • 幾種對(duì)已創(chuàng)建的dataframe進(jìn)行數(shù)據(jù)修改的方法
  • dataframe中兩個(gè)常用的函數(shù):groupby以及apply

我們首先導(dǎo)入需要的module:

In [1]: import pandas as pd
In [2]: import numpy as np

基本概念

series

series是pandas中基本的數(shù)據(jù)結(jié)構(gòu)钩蚊,它的結(jié)構(gòu)與一個(gè)list類似,但是卻擁有自己的索引蹈矮。在實(shí)際應(yīng)用中砰逻,dataframe的每一個(gè)列對(duì)一個(gè)series。正因?yàn)檫@些series和dataframe一樣都有索引泛鸟,因此在把一個(gè)series加入到dataframe中時(shí)蝠咆,必須考慮他們的索引是否對(duì)應(yīng)。

In [3]: s1 = pd.Series([1,3,5,6,8])

In [4]: s1
Out[4]: 
0    1
1    3
2    5
3    6
4    8
dtype: int64

In [5]: s2 = pd.Series(['a', 'b', 'c'])

In [6]: s2
Out[6]:
0    a
1    b
2    c
dtype: object

dataframe

pandas中的dataframe與R中的dataframe基本類似北滥,可以提供一種類似于表格的數(shù)據(jù)結(jié)構(gòu)刚操,每一列都是一個(gè)series,這些series擁有與整個(gè)dataframe相同的索引再芋。

In [7]: index = range(6)

In [8]: index
Out[8]: [0, 1, 2, 3, 4, 5]

In [9]: df = pd.DataFrame(np.random.randn(6,4), index=index, columns=list('ABCD'))

In [10]: df
Out[10]:
          A         B         C         D
0  0.531734 -1.292527 -0.627073 -1.900115
1 -0.715616  2.007529 -0.535181 -0.055376
2 -0.051779  0.751669 -1.150100  1.295839
3 -1.749876  0.962153  0.489654 -0.134320
4 -0.350185 -0.495535  0.116741  1.192340
5  0.844690 -0.111987 -1.221936 -0.714337

索引

索引在dataframe和series中都有應(yīng)用菊霜,簡(jiǎn)單來(lái)看,它是一種類似于整數(shù)array的數(shù)據(jù)結(jié)構(gòu)济赎。


In [11]: df.index
Out[11]: Int64Index([0, 1, 2, 3, 4, 5], dtype='int64')

In [12]: type(df.index)
Out[12]: pandas.indexes.numeric.Int64Index

但是需要注意的是鉴逞,并不是每一個(gè)dataframe和series的索引都一定是從0開始,在數(shù)據(jù)的操作過程中司训,索引有時(shí)候會(huì)發(fā)生變化华蜒。


In [13]: df2 = df[3:5]

In [14]: df2
Out[14]:
          A         B         C        D
3 -1.749876  0.962153  0.489654 -0.13432
4 -0.350185 -0.495535  0.116741  1.19234

In [15]: df2.index
Out[15]: Int64Index([3, 4], dtype='int64')

創(chuàng)建dataframe

pandas中的dataframe有很多不同的創(chuàng)建方式,比如可以手動(dòng)一個(gè)一個(gè)創(chuàng)建豁遭,也可以通過讀取文件或者數(shù)據(jù)庫(kù)直接生成叭喜,以下將一一給予簡(jiǎn)單介紹。

手動(dòng)創(chuàng)建

如果沒有已經(jīng)生成的文件或者數(shù)據(jù)庫(kù)的數(shù)據(jù)表蓖谢,我們可能需要手動(dòng)創(chuàng)建一個(gè)dataframe捂蕴,并在程序運(yùn)行過程中不斷賦值等等。手動(dòng)創(chuàng)建的基本命令就是pd.DataFrame(self, data=None, index=None, columns=None, dtype=None, copy=False)闪幽。

其參數(shù)包括data啥辨、indexcolumns盯腌、dtype溉知、copy,這里我將介紹前三個(gè)變量:

  • data: 將要存入dataframe的數(shù)據(jù),可以是numpy里面的matrix级乍,也可以是一個(gè)簡(jiǎn)單的2d list舌劳。
  • index: 一個(gè)可以作為dataframe索引的數(shù)列,注意玫荣,pandas不會(huì)檢查是否有重復(fù)元素甚淡,因此請(qǐng)?jiān)谧鳛樗饕褂们白孕袡z查,以免導(dǎo)致錯(cuò)誤
  • columns: 一個(gè)string的list捅厂,每一個(gè)元素代表一個(gè)列的名字贯卦,順序與列的順序相同

In [16]: index = [1, 1, 2, 3, 4]

In [17]: index
Out[17]: [1, 1, 2, 3, 4]

In [18]: data = [range(4), range(1, 5), range(2, 6), range(3, 7), range(4, 8)]

In [19]: data
Out[19]: [[0, 1, 2, 3], [1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6], [4, 5, 6, 7]]

In [20]: df2 = pd.DataFrame(data=data, index=index, columns=list('ABCD'))

In [21]: df2
Out[21]:
   A  B  C  D
1  0  1  2  3
1  1  2  3  4
2  2  3  4  5
3  3  4  5  6
4  4  5  6  7

從文件中讀取

以csv文件為例,使用read_csv函數(shù)即可焙贷。假設(shè)路徑內(nèi)有一個(gè)文件名為weather.csv撵割,其主要內(nèi)容如下:

,date,rain,snow,weather
0,20160101,0,0,0
1,20160102,0,0,0
2,20160103,0,0,0
3,20160104,0,0,0
4,20160105,0,0,0
5,20160106,0,0,0
6,20160107,0,0,0
7,20160108,0,0,0
8,20160109,1,0,1
9,20160110,1,0,1
10,20160111,0,0,0

其讀取過程如下:


In [22]: df2 = pd.read_csv('weather.csv')

In [23]: df2
Out[23]:
    Unnamed: 0      date  rain  snow  weather
0            0  20160101     0     0        0
1            1  20160102     0     0        0
2            2  20160103     0     0        0
3            3  20160104     0     0        0
4            4  20160105     0     0        0
5            5  20160106     0     0        0
6            6  20160107     0     0        0
7            7  20160108     0     0        0
8            8  20160109     1     0        1
9            9  20160110     1     0        1
10          10  20160111     0     0        0

這里,第一列在csv中沒有標(biāo)題辙芍,所以讀取后在dataframe里面的列名稱就叫Unnamed: 0睁枕。

從sql中讀取

如果要從sql中讀取,我們需要了解一點(diǎn)sql的基本知識(shí)沸手,同時(shí)在python中安裝sqlalchemy外遇,然后使用read_sql函數(shù)。
現(xiàn)假設(shè)我們的database中有一個(gè)數(shù)據(jù)表的名字就叫做weather,其內(nèi)容與csv文件基本一樣,那么示例如下(我們使用postgresql為例瑞驱,但是mysql等等基本相同):


In [24]: from sqlalchemy import create_engine

In [25]: database_engine = create_engine('postgresql://[用戶名]:[對(duì)應(yīng)密碼]@localhost:5432/[database名]', echo=False)

In [26]: weather_df = pd.read_sql("SELECT * FROM weather", con=database_engine)

In [27]: weather_df
Out[27]:
    id      date  rain  snow  weather
0    0  20160101     0     0        0
1    1  20160102     0     0        0
2    2  20160103     0     0        0
3    3  20160104     0     0        0
4    4  20160105     0     0        0
5    5  20160106     0     0        0
6    6  20160107     0     0        0
7    7  20160108     0     0        0
8    8  20160109     1     0        1
9    9  20160110     1     0        1
10  10  20160111     0     0        0

使用dataframe

dataframe的使用主要在于根據(jù)使用者的需要查看并獲取里面的數(shù)據(jù)。

查看數(shù)據(jù)

dataframe的查看主要包括了解整個(gè)數(shù)據(jù)表的基本信息菲语,了解里面的數(shù)據(jù)大致特征,并查看某特定幾行的數(shù)據(jù)惑灵。下面筆者將一一進(jìn)行介紹山上。

查看數(shù)據(jù)表的基本信息

使用info函數(shù)。


In [28]: weather_df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 11 entries, 0 to 10
Data columns (total 5 columns):
id         11 non-null int64
date       11 non-null int64
rain       11 non-null int64
snow       11 non-null int64
weather    11 non-null int64
dtypes: int64(5)
memory usage: 512.0 bytes

查看開頭或尾部的數(shù)據(jù)表

查看開頭:使用head函數(shù)
查看尾部:使用tail函數(shù)


In [30]: weather_df.head(5)
Out[30]:
   id      date  rain  snow  weather
0   0  20160101     0     0        0
1   1  20160102     0     0        0
2   2  20160103     0     0        0
3   3  20160104     0     0        0
4   4  20160105     0     0        0

In [31]: weather_df.tail(5)
Out[31]:
    id      date  rain  snow  weather
6    6  20160107     0     0        0
7    7  20160108     0     0        0
8    8  20160109     1     0        1
9    9  20160110     1     0        1
10  10  20160111     0     0        0

獲取數(shù)據(jù)

此處為了提高程序效率英支,推薦使用一下四個(gè)行數(shù)來(lái)獲取數(shù)據(jù): iloc佩憾、lociat干花、at妄帘。

獲取行或列

獲取多行

In [32]: weather_df[3:8]
Out[32]:
   id      date  rain  snow  weather
3   3  20160104     0     0        0
4   4  20160105     0     0        0
5   5  20160106     0     0        0
6   6  20160107     0     0        0
7   7  20160108     0     0        0

獲取單行

使用iloc或者loc


In [33]: weather_df.iloc[3]
Out[33]:
id                3
date       20160104
rain              0
snow              0
weather           0
Name: 3, dtype: int64

In [34]: weather_df.loc[3]
Out[34]:
id                3
date       20160104
rain              0
snow              0
weather           0
Name: 3, dtype: int64

此處的ilocloc結(jié)果相同池凄,但并不代表兩者意義一樣抡驼。loc通過索引獲得對(duì)應(yīng)行,iloc通過行號(hào)來(lái)獲得對(duì)應(yīng)行肿仑。例如(注意索引)


In [35]: df = weather_df[3:8]

In [36]: df
Out[36]:
   id      date  rain  snow  weather
3   3  20160104     0     0        0
4   4  20160105     0     0        0
5   5  20160106     0     0        0
6   6  20160107     0     0        0
7   7  20160108     0     0        0

In [37]: df.iloc[3]
Out[37]:
id                6
date       20160107
rain              0
snow              0
weather           0
Name: 6, dtype: int64

In [38]: df.loc[3]
Out[38]:
id                3
date       20160104
rain              0
snow              0
weather           0
Name: 3, dtype: int64

獲取單列

有兩種方式


In [39]: df.date
Out[39]:
3    20160104
4    20160105
5    20160106
6    20160107
7    20160108
Name: date, dtype: int64

In [40]: df['date']
Out[40]:
3    20160104
4    20160105
5    20160106
6    20160107
7    20160108
Name: date, dtype: int64

獲取多列

使用loc函數(shù)或iloc函數(shù)


In [41]: df.loc[:, ['date', 'snow']]
Out[41]:
       date  snow
3  20160104     0
4  20160105     0
5  20160106     0
6  20160107     0
7  20160108     0

In [42]: df.iloc[:, :2]
Out[42]:
   id      date
3   3  20160104
4   4  20160105
5   5  20160106
6   6  20160107
7   7  20160108

兩者的不同在于致盟,loc是使用索引和列名稱來(lái)獲得所需的列碎税,iloc是使用行號(hào)和列號(hào)來(lái)獲取所需的列。

獲取某個(gè)數(shù)據(jù)

要獲取某一個(gè)數(shù)值馏锡,iloc雷蹂、lociat眷篇、at都可以實(shí)現(xiàn)。


In [43]: df.iloc[3, 1]
Out[43]: 20160107

In [44]: df.iat[3, 1]
Out[44]: 20160107

In [45]: df.loc[3, 'date']
Out[45]: 20160104

In [46]: df.at[3, 'date']
Out[46]: 20160104

從該例子可以看出荔泳,ilociat都是通過行數(shù)和列數(shù)來(lái)獲取特定的單個(gè)元素蕉饼,而locat都是通過索引和列名稱來(lái)獲取特定的單個(gè)元素。

利用bool下標(biāo)來(lái)獲取數(shù)據(jù)

有些時(shí)候玛歌,我們只希望通過一些判斷或者比較獲得一部分?jǐn)?shù)據(jù)昧港,例如,在weather_df中支子,我希望獲得以下幾組數(shù)據(jù):

  • 獲取日期在20160106到20160110(包括首尾)之間的所有行
  • 獲取名稱為weather的列中值為1的所有行
  • 獲取日期在[20160106, 20160104, 20160108]這個(gè)list中的所有行
  • 以上三組數(shù)據(jù)中创肥,每組我只想獲得id, date和weather這三列

示例將按順序完成以上幾項(xiàng):


In [47]: weather_df[(weather_df['date'] >= 20160106) & (weather_df['date'] <= 20160110)]
Out[47]:
   id      date  rain  snow  weather
5   5  20160106     0     0        0
6   6  20160107     0     0        0
7   7  20160108     0     0        0
8   8  20160109     1     0        1
9   9  20160110     1     0        1

In [48]: weather_df[weather_df['weather'] == 1]
Out[48]:
   id      date  rain  snow  weather
8   8  20160109     1     0        1
9   9  20160110     1     0        1

In [49]: weather_df[weather_df.date.isin([20160106, 20160104, 20160108])]
Out[49]:
   id      date  rain  snow  weather
3   3  20160104     0     0        0
5   5  20160106     0     0        0
7   7  20160108     0     0        0

In [50]: weather_df[(weather_df['date'] >= 20160106) & (weather_df['date'] <= 20160110)].loc[:, ['id', 'date', 'weather']]
Out[50]:
   id      date  weather
5   5  20160106        0
6   6  20160107        0
7   7  20160108        0
8   8  20160109        1
9   9  20160110        1

In [51]: weather_df[weather_df['weather'] == 1].loc[:, ['id', 'date', 'weather']]
Out[51]:
   id      date  weather
8   8  20160109        1
9   9  20160110        1

In [52]: weather_df[weather_df.date.isin([20160106, 20160104, 20160108])].loc[:, ['id', 'date', 'weather']]
Out[52]:
   id      date  weather
3   3  20160104        0
5   5  20160106        0
7   7  20160108        0

通過上述幾個(gè)例子,我們可以發(fā)現(xiàn)通過條件判斷來(lái)獲取部分?jǐn)?shù)據(jù)的基本格式就是類似于dataframe[dataframe.column > value] 或者dataframe[dataframe.column.isin(list)]值朋。

那么其原理呢叹侄?

事實(shí)上他們先根據(jù)方括號(hào)內(nèi)的條件判斷生成了一個(gè)由bool值構(gòu)成的series: (weather_df['date'] >= 20160106) & (weather_df['date'] <= 20160110), weather_df['weather'] == 1或者weather_df.date.isin([20160106, 20160104, 20160108])
然后在根據(jù)這個(gè)新的series來(lái)選取bool值為true的行昨登。


In [53]: weather_df
Out[53]:
    id      date  rain  snow  weather
0    0  20160101     0     0        0
1    1  20160102     0     0        0
2    2  20160103     0     0        0
3    3  20160104     0     0        0
4    4  20160105     0     0        0
5    5  20160106     0     0        0
6    6  20160107     0     0        0
7    7  20160108     0     0        0
8    8  20160109     1     0        1
9    9  20160110     1     0        1
10  10  20160111     0     0        0

In [54]: weather_df.date.isin([20160106, 20160104, 20160108])
Out[54]:
0     False
1     False
2     False
3      True
4     False
5      True
6     False
7      True
8     False
9     False
10    False
Name: date, dtype: bool

In [55]: weather_df[weather_df.date.isin([20160106, 20160104, 20160108])]
Out[55]:
   id      date  rain  snow  weather
3   3  20160104     0     0        0
5   5  20160106     0     0        0
7   7  20160108     0     0        0

常用到的判斷主要包括數(shù)值的大小以及元素是否在給定的list或者set中趾代,前者用>, >=, <, 或者<=,后者用.isin丰辣。多個(gè)邏輯判斷的連接使用&或者|撒强。
當(dāng)然也存在更加復(fù)雜的邏輯判斷,比如判定某一個(gè)dataframe中某一個(gè)string構(gòu)成的列的每一個(gè)元素的第三到第六個(gè)構(gòu)成的substring必須在某個(gè)給定區(qū)間笙什,我的常用方法是使用apply函數(shù)飘哨,這部分內(nèi)容將在后面給出解釋和示例。

剩下的在后半部繼續(xù)寫吧琐凭。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末芽隆,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子统屈,更是在濱河造成了極大的恐慌摆马,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,042評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鸿吆,死亡現(xiàn)場(chǎng)離奇詭異囤采,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)惩淳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門蕉毯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)乓搬,“玉大人,你說(shuō)我怎么就攤上這事代虾〗希” “怎么了?”我有些...
    開封第一講書人閱讀 156,674評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵棉磨,是天一觀的道長(zhǎng)江掩。 經(jīng)常有香客問我,道長(zhǎng)乘瓤,這世上最難降的妖魔是什么环形? 我笑而不...
    開封第一講書人閱讀 56,340評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮衙傀,結(jié)果婚禮上抬吟,老公的妹妹穿的比我還像新娘。我一直安慰自己统抬,他們只是感情好火本,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,404評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著聪建,像睡著了一般钙畔。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上金麸,一...
    開封第一講書人閱讀 49,749評(píng)論 1 289
  • 那天刃鳄,我揣著相機(jī)與錄音,去河邊找鬼钱骂。 笑死叔锐,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的见秽。 我是一名探鬼主播愉烙,決...
    沈念sama閱讀 38,902評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼解取!你這毒婦竟也來(lái)了步责?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,662評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤禀苦,失蹤者是張志新(化名)和其女友劉穎蔓肯,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體振乏,經(jīng)...
    沈念sama閱讀 44,110評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蔗包,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了慧邮。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片调限。...
    茶點(diǎn)故事閱讀 38,577評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡舟陆,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出耻矮,到底是詐尸還是另有隱情秦躯,我是刑警寧澤,帶...
    沈念sama閱讀 34,258評(píng)論 4 328
  • 正文 年R本政府宣布裆装,位于F島的核電站踱承,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏哨免。R本人自食惡果不足惜茎活,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,848評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望铁瞒。 院中可真熱鬧妙色,春花似錦桅滋、人聲如沸慧耍。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)芍碧。三九已至,卻和暖如春号俐,著一層夾襖步出監(jiān)牢的瞬間泌豆,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工吏饿, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留踪危,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,271評(píng)論 2 360
  • 正文 我出身青樓猪落,卻偏偏與公主長(zhǎng)得像贞远,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子笨忌,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,452評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容