利用python進(jìn)行數(shù)據(jù)分析之pandas入門(一)

目錄:

5.1 pandas 的數(shù)據(jù)結(jié)構(gòu)介紹

5.1.1 Series

5.1.2 DataFrame

5.1.3索引對(duì)象

5.2基本功能

5.2.1重新索引

5.2.2丟棄指定軸上的項(xiàng)

5.2.3索引、選取和過濾

5.2.4算術(shù)運(yùn)算和數(shù)據(jù)對(duì)齊

5.2.4.1在算術(shù)方法中填充值

5.2.4.2 DataFrame和Series之間的運(yùn)算

5.2.5函數(shù)應(yīng)用和映射

5.2.6排序和排名

5.2.7帶有重復(fù)的軸索引

5.3匯總和計(jì)算描述性統(tǒng)計(jì)

5.3.1相關(guān)系數(shù)和協(xié)方差

5.3.2唯一值、值計(jì)數(shù)以及成員資格

5.4處理缺失數(shù)據(jù)

5.4.1濾除缺失數(shù)據(jù)

5.4.2填充缺失數(shù)據(jù)

5.5層次化索引

5.5.1重排分級(jí)順序

5.5.2根據(jù)級(jí)別匯總統(tǒng)計(jì)

5.5.3使用DataFrame的列

5.6其他有關(guān)pandas的話題

5.6.1整數(shù)索引

第5章 pandas入門

pandas 引入約定

In [1]: from pandas import Series,DataFrame

In [2]: import pandas as pd

5.1 pandas 的數(shù)據(jù)結(jié)構(gòu)介紹

要使用pandas帅刊,首先要熟悉他的兩個(gè)主要的數(shù)據(jù)結(jié)構(gòu):Series和DataFrame全闷。

5.1.1 Series

Series 是一種類似于一維數(shù)組的對(duì)象,由一組數(shù)據(jù)(各種numpy數(shù)據(jù)類型)以及一組與之相關(guān)的數(shù)據(jù)標(biāo)簽(即索引)組成潘鲫。

僅由一組數(shù)據(jù)即可產(chǎn)生最簡單的Series:

In [3]: obj=Series([4,7,-5,3])

In [4]: obj

Out[4]:

0? ? 4

1? ? 7

2? -5

3? ? 3

dtype: int64

serice 的字符串表現(xiàn)形式為:索引在左邊翁逞,值在右邊。

由于我們沒有為數(shù)據(jù)指定索引溉仑,于是會(huì)自動(dòng)創(chuàng)建一個(gè)0到N-1(N位數(shù)據(jù)的長度)的整數(shù)的索引挖函。

可以通過series的values和index屬性獲取其數(shù)組表現(xiàn)形式和索引對(duì)象。

In [6]: obj.values #表現(xiàn)形式

Out[6]: array([ 4,? 7, -5,? 3], dtype=int64)

In [7]: obj.index #索引對(duì)象

Out[7]: RangeIndex(start=0, stop=4, step=1)

通常我們希望所創(chuàng)建的Series帶有一個(gè)可以對(duì)各個(gè)數(shù)據(jù)點(diǎn)進(jìn)行標(biāo)記的索引:

In [11]: obj2['a']

Out[11]: -5

In [12]: obj2['d']=6

In [13]: obj2[['c','a','d']]

Out[13]:

c? ? 3

a? -5

d? ? 6

dtype: int64

NumPy數(shù)組運(yùn)算(若根據(jù)布爾型數(shù)組進(jìn)行過濾浊竟,標(biāo)量乘法怨喘,應(yīng)用數(shù)學(xué)函數(shù)等)都會(huì)保留索引和值之間的鏈接:

In [14]: obj2

Out[14]:

d? ? 6

b? ? 7

a? -5

c? ? 3

dtype: int64

In [15]: obj2[obj2>0]

Out[15]:

d? ? 6

b? ? 7

c? ? 3

dtype: int64

In [16]: obj2*2

Out[16]:

d? ? 12

b? ? 14

a? -10

c? ? 6

dtype: int64

In [19]: np.exp(obj2)

Out[19]:

d? ? 403.428793

b? ? 1096.633158

a? ? ? 0.006738

c? ? ? 20.085537

dtype: float64

我們也可以將Serice看成一個(gè)定長的有序字典,因?yàn)樗撬饕档綌?shù)據(jù)值的一個(gè)映射振定”亓可以用在許多原本需要字典參數(shù)的函數(shù)中:

In [20]: 'b' in obj2

Out[20]: True

In [21]: 'e' in obj2

Out[21]: False

如果數(shù)據(jù)被存放在一個(gè)python字典中,可以直接通過這個(gè)字典來創(chuàng)建Series

In [4]: sdata={'Ohio':35000,'Texas':71000,'Oregon':16000,'Utah':5000}

In [5]: obj3=Series(sdata)

In [6]: obj3

Out[6]:

Ohio? ? ? 35000

Oregon? ? 16000

Texas? ? 71000

Utah? ? ? 5000

dtype: int64

只傳入一個(gè)字典后频,則結(jié)果Series中索引就是原字典的鍵(有序排列)

In [7]: states=['California','Ohio','Oregon','Texas']

In [8]: obj4=Series(sdata,index=states)

In [9]: obj4

Out[9]:

California? ? ? ? NaN? ? #“California ”的值找不到梳庆,結(jié)果用NaN來代替。

Ohio? ? ? ? ? 35000.0

Oregon? ? ? ? 16000.0

Texas? ? ? ? 71000.0

dtype: float64

pandas的isnull和notnull函數(shù)可以用于檢測缺失數(shù)據(jù):

In [10]: pd.isnull(obj4)

Out[10]:

California? ? True

Ohio? ? ? ? ? False

Oregon? ? ? ? False

Texas? ? ? ? False

dtype: bool

In [11]: pd.notnull(obj4)

Out[11]:

California? ? False

Ohio? ? ? ? ? True

Oregon? ? ? ? True

Texas? ? ? ? ? True

dtype: bool

Series也有類似的實(shí)例方法:

In [12]: obj4.isnull()

Out[12]:

California? ? True

Ohio? ? ? ? ? False

Oregon? ? ? ? False

Texas? ? ? ? False

dtype: bool

Series重要的一個(gè)功能是:它在算術(shù)中會(huì)自動(dòng)對(duì)齊不同索引的數(shù)據(jù)卑惜。

In [13]: obj3

Out[13]:

Ohio? ? ? 35000

Oregon? ? 16000

Texas? ? 71000

Utah? ? ? 5000

dtype: int64

In [14]: obj4

Out[14]:

California? ? ? ? NaN

Ohio? ? ? ? ? 35000.0

Oregon? ? ? ? 16000.0

Texas? ? ? ? 71000.0

dtype: float64

In [15]: obj3+obj4

Out[15]:

California? ? ? ? NaN

Ohio? ? ? ? ? 70000.0

Oregon? ? ? ? 32000.0

Texas? ? ? ? 142000.0

Utah? ? ? ? ? ? ? NaN

dtype: float64

Series對(duì)象本身及其索引都有一個(gè)name屬性膏执,該屬性跟pandas其他關(guān)鍵功能關(guān)系非常密切:

In [16]: obj4.name='population'

In [17]: obj4.index.name='state'

In [18]: obj4

Out[18]:

state

California? ? ? ? NaN

Ohio? ? ? ? ? 35000.0

Oregon? ? ? ? 16000.0

Texas? ? ? ? 71000.0

Name: population, dtype: float64

Series 的索引可以通過賦值的方式就地修改:

In [20]: obj=Series([4,7,-5,3])

In [21]: obj.index=['Bob','Steve','Jeff','Ryan']

In [22]: obj

Out[22]:

Bob? ? ? 4

Steve? ? 7

Jeff? ? -5

Ryan? ? 3

dtype: int64

5.1.2 DataFrame

DataFrame是一個(gè)表格型的數(shù)據(jù)結(jié)構(gòu),含有一組有序的列残揉,每列可以是不同的值類型(數(shù)值胧后,字符串,布爾值等)

DataFrame既有行索引也有列索引抱环,可以被看做是由Series組成的字典壳快。

跟其他的類似的數(shù)據(jù)結(jié)構(gòu)相比(如R的data.frame),DataFrame中面向行和列的操作基本是平衡的镇草。

DataFrame中的數(shù)據(jù)是以一個(gè)或多個(gè)二維塊存放的眶痰。

構(gòu)建DataFrame的辦法有很多,最常用的一種是直接傳入一個(gè)由等長列表或numpy組成的數(shù)組組成的字典:

In [5]: from pandas import Series,DataFrame

In [6]: import pandas as pd

In [7]: data={'state':['Ohio','Ohio','Ohio','Nevada','Nevada'],'year':[2000,2001,2002,2001,2002],'pop':[1.5,1.7,3.6,2.4,2.9]}

In [8]: frame=DataFrame(data)

結(jié)果DataFrame'會(huì)自動(dòng)加上索引(跟Series一樣)梯啤,且全部列會(huì)被有序排列:

In [10]: frame

Out[10]:

pop? state? year

0? 1.5? ? Ohio? 2000

1? 1.7? ? Ohio? 2001

2? 3.6? ? Ohio? 2002

3? 2.4? Nevada? 2001

4? 2.9? Nevada? 2002

指定列序列竖伯,DataFrame的列就會(huì)按照指定順序進(jìn)行排列:

In [11]: DataFrame(data,columns=['year','state','pop'])

Out[11]:

year? state? pop

0? 2000? ? Ohio? 1.5

1? 2001? ? Ohio? 1.7

2? 2002? ? Ohio? 3.6

3? 2001? Nevada? 2.4

4? 2002? Nevada? 2.9

跟Series一樣,如果傳入的列在數(shù)據(jù)中找不到,就會(huì)產(chǎn)生NA值:

In [11]:? frame2=DataFrame(data,columns=['year','state','pop','debt']

...: ,index=['one','two','three','four','five'])

In [12]: frame2

Out[12]:

year? state? pop debt

one? ? 2000? ? Ohio? 1.5? NaN

two? ? 2001? ? Ohio? 1.7? NaN

three? 2002? ? Ohio? 3.6? NaN

four? 2001? Nevada? 2.4? NaN

five? 2002? Nevada? 2.9? NaN

In [26]: frame2.columns

Out[26]: Index([u'years', u'state', u'pop', u'debt'], dtype='object')

通過類似于字典標(biāo)記的方式或?qū)傩缘姆绞狡哂ぃ梢詫ataFrame的列獲取為一個(gè)Series:

In [27]: frame2['state']

Out[27]:

one? ? ? ? Ohio

two? ? ? ? Ohio

three? ? ? Ohio

four? ? Nevada

five? ? Nevada

Name: state, dtype: object

In [18]: frame2.year

Out[18]:

one? ? ? 2000

two? ? ? 2001

three? ? 2002

four? ? 2001

five? ? 2002

Name: year, dtype: int64

注意祟偷,返回的Series擁有原DataFrame相同的索引,且其name屬性也已經(jīng)被相應(yīng)的設(shè)置好了打厘。

行也可以通過位置或名稱的方式來進(jìn)行獲取修肠。

In [19]: frame2.ix['three']

Out[19]:

year? ? 2002

state? ? Ohio

pop? ? ? 3.6

debt? ? ? NaN

Name: three, dtype: object

列可以通過賦值的方式進(jìn)行修改。如下户盯,我們可以給空的”debt“列賦值一個(gè)標(biāo)量或一組值嵌施。

In [20]: frame2['debt']=16.5

In [21]: frame2

Out[21]:

year? state? pop? debt

one? ? 2000? ? Ohio? 1.5? 16.5

two? ? 2001? ? Ohio? 1.7? 16.5

three? 2002? ? Ohio? 3.6? 16.5

four? 2001? Nevada? 2.4? 16.5

five? 2002? Nevada? 2.9? 16.5

In [24]: frame2['debt']=np.arange(5.)

In [25]: frame2

Out[25]:

year? state? pop? debt

one? ? 2000? ? Ohio? 1.5? 0.0

two? ? 2001? ? Ohio? 1.7? 1.0

three? 2002? ? Ohio? 3.6? 2.0

four? 2001? Nevada? 2.4? 3.0

five? 2002? Nevada? 2.9? 4.0

將列表或數(shù)組賦值給某個(gè)列的時(shí)候,其長度必須要跟DataFrame的長度向匹配莽鸭。如果賦值的是一個(gè)個(gè)Series 吗伤,就會(huì)精確的匹配DataFrame的索引,所有的空位都將被填上的缺失值硫眨。

In [26]: val=Series([-1.2,-1.5,-1.7],index=['two','four','five'])

In [27]: frame2['debt']=val

In [28]: frame2

Out[28]:

year? state? pop? debt

one? ? 2000? ? Ohio? 1.5? NaN

two? ? 2001? ? Ohio? 1.7? -1.2

three? 2002? ? Ohio? 3.6? NaN

four? 2001? Nevada? 2.4? -1.5

five? 2002? Nevada? 2.9? -1.7

為不存在的列賦值會(huì)創(chuàng)建一個(gè)新列足淆。關(guān)鍵字del用于刪除列:

In [29]: frame2['eastern']=frame2.state=='Ohio'

In [30]: frame2

Out[30]:

year? state? pop? debt eastern

one? ? 2000? ? Ohio? 1.5? NaN? ? True

two? ? 2001? ? Ohio? 1.7? -1.2? ? True

three? 2002? ? Ohio? 3.6? NaN? ? True

four? 2001? Nevada? 2.4? -1.5? False

five? 2002? Nevada? 2.9? -1.7? False

In [31]: del frame2['eastern']

In [32]: frame2.columns

Out[32]: Index([u'year', u'state', u'pop', u'debt'], dtype='object')

另一種常見的數(shù)據(jù)形式是嵌套字典(也就是字典的字典):

In [33]: pop={'Nevada':{2001:2.4,2002:2.9},'Ohio':{2000:1.5,2001:1.7,

...: 2002:3.6}}

將它傳給DataFrame,就會(huì)被解釋為:外層字典的鍵作為列捺球,內(nèi)層鍵作為行索引缸浦。

In [34]: frame3=DataFrame(pop)

In [35]: frame3

Out[35]:

Nevada? Ohio

2000? ? NaN? 1.5

2001? ? 2.4? 1.7

2002? ? 2.9? 3.6

也可以對(duì)結(jié)果進(jìn)行轉(zhuǎn)置:

In [36]: frame3.T

Out[36]:

2000? 2001? 2002

Nevada? NaN? 2.4? 2.9

Ohio? ? 1.5? 1.7? 3.6

內(nèi)層字典的鍵會(huì)被合并、排序以及形成最終的索引氮兵。若指定了顯式索引裂逐,則不會(huì)這樣:

In [37]: DataFrame(pop,index=[2001,2002,2003])

Out[37]:

Nevada? Ohio

2001? ? 2.4? 1.7

2002? ? 2.9? 3.6

2003? ? NaN? NaN

由Series組成的字典差不多也是一樣的用法:

In [40]: pdata={'Ohio':frame3['Ohio'][:-1],'Nevada':frame3['Nevada'][:2]}

In [41]: DataFrame(pdata)

Out[41]:

Nevada? Ohio

2000? ? NaN? 1.5

2001? ? 2.4? 1.7

如果設(shè)置了Data.Frame的index屬性和columns的name屬性,

In [42]: frame3.index.name='year';frame3.columns.name='state'

In [43]: frame3

Out[43]:

state? Nevada? Ohio

year

2000? ? ? NaN? 1.5

2001? ? ? 2.4? 1.7

2002? ? ? 2.9? 3.6

In [44]: frame3.values

Out[44]:

array([[ nan,? 1.5],

[ 2.4,? 1.7],

[ 2.9,? 3.6]])

In [45]: frame3.values

Out[45]:

array([[ nan,? 1.5],

[ 2.4,? 1.7],

[ 2.9,? 3.6]])

5.1.3索引對(duì)象

pandas的索引對(duì)象負(fù)責(zé)管理標(biāo)簽和其他元數(shù)據(jù)(比如軸名稱等)泣栈。構(gòu)建Series或DataFrame時(shí)卜高,所用到的任何數(shù)組或其他序列的標(biāo)簽都會(huì)被轉(zhuǎn)換成一個(gè)Index:

In [2]: import numpy as np

In [3]: import pandas as pd

In [5]: from pandas import Series,DataFrame

In [6]: obj=Series(range(3),index=['a','b','c'])

In [7]: index=obj.index

In [8]: index

Out[8]: Index([u'a', u'b', u'c'], dtype='object')

In [9]: index[1:]

Out[9]: Index([u'b', u'c'], dtype='object')

Index對(duì)象是不可修改的,因此用戶不能對(duì)其修改:

In [10]: index[1]='d'

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

TypeError? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Traceback (most recent call last)

in ()

----> 1 index[1]='d'

H:\Anaconda2-4.3.0.1\lib\site-packages\pandas\indexes\base.pyc in __setitem__(self, key, value)

1402

1403? ? def __setitem__(self, key, value):

-> 1404? ? ? ? raise TypeError("Index does not support mutable operations")

1405

1406? ? def __getitem__(self, key):

TypeError: Index does not support mutable operations

不可修改性非常重要南片,因?yàn)檫@樣才能使得index對(duì)象在多個(gè)數(shù)據(jù)結(jié)構(gòu)之間安全共享:

In [12]: index=pd.Index(np.arange(3))

In [13]: obj2=Series([1.5,-2.5,0],index=index)

In [14]: obj2=Series([1.5,-2.5,0],index=index)

In [16]: obj2.index is index

Out[16]: True

除了長得像數(shù)組掺涛,index的功能也類似一個(gè)固定大小的集合:

In [43]: frame3

Out[43]:

state? Nevada? Ohio

year

2000? ? ? NaN? 1.5

2001? ? ? 2.4? 1.7

2002? ? ? 2.9? 3.6

In [46]: 'Ohio' in frame3.columns

Out[46]: True

In [47]: 2003 in frame3.index

Out[47]: False

5.2基本功能

介紹操作Series和DataFrame中的數(shù)據(jù)的基本手段。

5.2.1重新索引

pandas對(duì)象的一個(gè)重要的方法就是reindex疼进,作用是創(chuàng)建一個(gè)適應(yīng)新索引的新對(duì)象薪缆。

In [33]:? import pandas as pd

from pandas import Series,DataFrame

In [34]: obj=Series([4.5,7.2,-5.3,3.6],index=['d','b','a','c'])

In [35]: obj

Out[35]:

d? ? 4.5

b? ? 7.2

a? -5.3

c? ? 3.6

dtype: float64

調(diào)用該Series的reindex將會(huì)根據(jù)新索引進(jìn)行重排。如果某個(gè)索引值當(dāng)前不存,就引入缺失值:

In [36]: obj2=obj.reindex(['a','b','c','d','e'])

In [37]: obj2

Out[37]:

a? -5.3

b? ? 7.2

c? ? 3.6

d? ? 4.5

e? ? NaN

dtype: float64

In [38]:? obj.reindex(['a','b','c','d','e'],fill_value=0)

Out[38]:

a? -5.3

b? ? 7.2

c? ? 3.6

d? ? 4.5

e? ? 0.0

dtype: float64

對(duì)于時(shí)間序列這樣的有序數(shù)據(jù)伞广,重新索引時(shí)可能需要做一些插值處理拣帽。method選項(xiàng)即可用達(dá)到此目的。例如:ffill可以實(shí)現(xiàn)向前值填充:

In [39]: obj3=Series(['blue','purple','yellow'],index=[0,2,4])

In [40]: obj3.reindex(range(6),method='ffill')

Out[40]:

0? ? ? blue

1? ? ? blue

2? ? purple

3? ? purple

4? ? yellow

5? ? yellow

dtype: object

下表中列出了可用的method選項(xiàng)嚼锄。

參數(shù) 說明

fill或pad 前向填充(或搬運(yùn))值

bfill或backfill 后向填充(或搬運(yùn))值

對(duì)于DataFrame减拭,reindex可以修改(行)索引,列区丑,或兩個(gè)都修改拧粪。如果僅傳入一個(gè)序列修陡,則會(huì)重新索引行:

In [41]: frame=DataFrame(np.arange(9).reshape((3,3)),index=['a','c','d'],columns=['Ohio','Texas','California',])

In [52]: frame

Out[53]:

Ohio? Texas? California

a? ? 0? ? ? 1? ? ? ? ? 2

c? ? 3? ? ? 4? ? ? ? ? 5

d? ? 6? ? ? 7? ? ? ? ? 8

In [54]: frame2=frame.reindex(['a','b','c','d'])

In [55]:frame2

Out[55]:

Ohio? Texas? California

a? 0.0? ? 1.0? ? ? ? 2.0

b? NaN? ? NaN? ? ? ? NaN

c? 3.0? ? 4.0? ? ? ? 5.0

d? 6.0? ? 7.0? ? ? ? 8.0

使用columns關(guān)鍵字即可以重新索引。

In [56]: states=['Texas','Utah','California']

frame.reindex(columns=states)

Out[57]:

Texas? Utah? California

a? ? ? 1? NaN? ? ? ? ? 2

c? ? ? 4? NaN? ? ? ? ? 5

d? ? ? 7? NaN? ? ? ? ? 8

也可以同時(shí)對(duì)行和列進(jìn)行重新索引可霎,而插值則只能按行應(yīng)用(即軸0):

frame.reindex(index=['a','b','c','d'],method='ffill',columns=states)

Out[58]:

Texas? Utah? California

a? ? ? 1? NaN? ? ? ? ? 2

b? ? ? 1? NaN? ? ? ? ? 2

c? ? ? 4? NaN? ? ? ? ? 5

d? ? ? 7? NaN? ? ? ? ? 8

利用ix的標(biāo)簽的=索引功能魄鸦,重新索引任務(wù)可以變得簡潔:

frame.ix[['a','b','c','d'],states]

Out[59]:

Texas? Utah? California

a? ? 1.0? NaN? ? ? ? 2.0

b? ? NaN? NaN? ? ? ? NaN

c? ? 4.0? NaN? ? ? ? 5.0

d? ? 7.0? NaN? ? ? ? 8.0

5.2.2丟棄指定軸上的項(xiàng)

丟棄某條軸上的一個(gè)或多個(gè)項(xiàng),只要有一個(gè)索引數(shù)組或列表即可癣朗。

由于需要執(zhí)行一些數(shù)據(jù)整理和集合邏輯号杏,所以drop方法返回的是一個(gè)在指定軸上刪除了指定值的新對(duì)象:

In [60]: obj=Series(np.arange(5.),index=['a','b','c','d','e'])

In [61]: new_obj=obj.drop('c')

In [62]: new_obj

Out[62]:

a? ? 0.0

b? ? 1.0

d? ? 3.0

e? ? 4.0

dtype: float64

In[63]: obj.drop(['d','c'])

Out[63]:

a? ? 0.0

b? ? 1.0

e? ? 4.0

dtype: float64

對(duì)于DataFrame,可以刪除任意軸上的索引值:

In [66]: data=DataFrame(np.arange(16).reshape((4,4)),index=['Ohio','Colorado','Utah','New York'],columns=['one','two','three','four'])

In[67]: data.drop(['Colorado','Ohio'])

Out[67]:

one? two? three? four

Utah? ? ? ? 8? ? 9? ? 10? ? 11

New York? 12? 13? ? 14? ? 15

In [68]: data.drop('two',axis=1)

Out[68]:

one? three? four

Ohio? ? ? ? 0? ? ? 2? ? 3

Colorado? ? 4? ? ? 6? ? 7

Utah? ? ? ? 8? ? 10? ? 11

New York? 12? ? 14? ? 15

In [69]: data.drop(['two','four'],axis=1)

Out[69]:

one? three

Ohio? ? ? ? 0? ? ? 2

Colorado? ? 4? ? ? 6

Utah? ? ? ? 8? ? 10

New York? 12? ? 14

5.2.3索引斯棒、選取和過濾

Series索引 (obj[...])的工作方式類似于NumPy數(shù)組的索引,只不過Series的索引值不只是整數(shù)主经。例:

In [5]: obj=Series(np.arange(4.),index=['a','b','c','d'])

In [6]: obj['b']

Out[6]: 1.0

In [7]: obj[1]

Out[7]: 1.0

In [8]: obj[2:4]

Out[8]:

c? ? 2.0

d? ? 3.0

dtype: float64

In [10]: obj[['b','a','d']]

Out[10]:

b? ? 1.0

a? ? 0.0

d? ? 3.0

dtype: float64

In [11]: obj[[1,3]]

Out[11]:

b? ? 1.0

d? ? 3.0

dtype: float64

In [12]: obj[obj<2]

Out[12]:

a? ? 0.0

b? ? 1.0

dtype: float64

利用標(biāo)簽的切片運(yùn)算與普通的python切片運(yùn)算不同荣暮,其末端是包含的(inclusive)

In [19]: obj['b':'c']

Out[19]:

b? ? 1.0

c? ? 2.0

dtype: float64

設(shè)置方式如下:

In [20]: obj['b':'c']=5

In [21]: obj

Out[21]:

a? ? 0.0

b? ? 5.0

c? ? 5.0

d? ? 3.0

dtype: float64

如你所見,對(duì)DataFrame進(jìn)行索引其實(shí)就是獲取一個(gè)或多個(gè)列:

In [24]: data=DataFrame(np.arange(16).reshape((4,4)),

index=['Ohio','Colorado','Utah','New York'],columns=['one','two','three','four'])

In [25]: data

Out[25]:

one? two? three? four

Ohio? ? ? ? 0? ? 1? ? ? 2? ? 3

Colorado? ? 4? ? 5? ? ? 6? ? 7

Utah? ? ? ? 8? ? 9? ? 10? ? 11

New York? 12? 13? ? 14? ? 15

In [26]: data['two']

Out[26]:

Ohio? ? ? ? 1

Colorado? ? 5

Utah? ? ? ? 9

New York? ? 13

Name: two, dtype: int32

In [28]: data[['three','one']]

Out[28]:

three? one

Ohio? ? ? ? ? 2? ? 0

Colorado? ? ? 6? ? 4

Utah? ? ? ? 10? ? 8

New York? ? 14? 12

In [30]: data[['three','one']]

Out[30]:

three? one

Ohio? ? ? ? ? 2? ? 0

Colorado? ? ? 6? ? 4

Utah? ? ? ? 10? ? 8

New York? ? 14? 12

這種索引方式有幾個(gè)特殊情況罩驻。首先通過切片或布爾數(shù)組進(jìn)行選取行:

In [29]: data[:2]

Out[29]:

one? two? three? four

Ohio? ? ? ? 0? ? 1? ? ? 2? ? 3

Colorado? ? 4? ? 5? ? ? 6? ? 7

In [31]: data[data['three']>5]

Out[31]:

one? two? three? four

Colorado? ? 4? ? 5? ? ? 6? ? 7

Utah? ? ? ? 8? ? 9? ? 10? ? 11

New York? 12? 13? ? 14? ? 15

另一種用法使通過布爾型DataFrame進(jìn)行索引:

In [32]: data<5

Out[32]:

one? ? two? three? four

Ohio? ? ? True? True? True? True

Colorado? True? False? False? False

Utah? ? ? False? False? False? False

New York? False? False? False? False

In [33]: data[data<5]=0

In [34]: data

Out[34]:

one? two? three? four

Ohio? ? ? ? 0? ? 0? ? ? 0? ? 0

Colorado? ? 0? ? 5? ? ? 6? ? 7

Utah? ? ? ? 8? ? 9? ? 10? ? 11

New York? 12? 13? ? 14? ? 15

這段代碼使得DataFrame在語法上像ndarray

為了在DataFrame的行上進(jìn)行標(biāo)簽索引穗酥,我們引入專門的索引字段ix。使得你通過numpy式的標(biāo)記法以及軸標(biāo)簽的從DataFrame中選取行和列的子集惠遏。這是重現(xiàn)索引的簡單手段:

In [35]: data.ix['Colorado',['two','three']]

Out[35]:

two? ? ? 5

three? ? 6

Name: Colorado, dtype: int32

In [36]: data.ix[['Colorado','Utah'],[3,0,1]]

Out[36]:

four? one? two

Colorado? ? 7? ? 0? ? 5

Utah? ? ? ? 11? ? 8? ? 9

In [37]: data.ix[2]

Out[37]:

one? ? ? 8

two? ? ? 9

three? ? 10

four? ? 11

Name: Utah, dtype: int32

In [38]: data.ix[:'Utah','two']

Out[38]:

Ohio? ? ? ? 0

Colorado? ? 5

Utah? ? ? ? 9

Name: two, dtype: int32

In [39]: data.ix[data.three>5,:3]

Out[39]:

one? two? three

Colorado? ? 0? ? 5? ? ? 6

Utah? ? ? ? 8? ? 9? ? 10

New York? 12? 13? ? 14

5.2.4算術(shù)運(yùn)算和數(shù)據(jù)對(duì)齊

In [5]: s1=Series([7.3,-2.5,3.4,1.5],index=['a','c','d','e'])

In [6]: s2=Series([-2.1,3.6,-1.5,4,3.1],index=['a','c','e','f','g'])

In [7]: s1

Out[7]:

a 7.3

c -2.5

d 3.4

e 1.5

dtype: float64

In [8]: s2

Out[8]:

a -2.1

c 3.6

e -1.5

f 4.0

g 3.1

dtype: float64

把他們相加:

In [9]: s1+s2

Out[9]:

a 5.2

c 1.1

d NaN

e 0.0

f NaN

g NaN

dtype: float64

自動(dòng)的數(shù)據(jù)對(duì)其操作在不重疊的索引處引入了NA值砾跃。缺失值會(huì)在算術(shù)運(yùn)算過程中傳播。

對(duì)于DataFrame节吮,對(duì)齊操作會(huì)同時(shí)發(fā)生在行和列上:

In [6]: df1=DataFrame(np.arange(9.).reshape((3,3)),columns=list('bcd'),index=['Ohio','Texas','Colorado'])

In [7]: df2=DataFrame(np.arange(12.).reshape((4,3)),columns=list('bde'),index=['Utah','Ohio','Texas','Oregon'])

In [8]: df1

Out[8]:

b c d

Ohio 0.0 1.0 2.0

Texas 3.0 4.0 5.0

Colorado 6.0 7.0 8.0

In [9]: df2

Out[9]:

b d e

Utah 0.0 1.0 2.0

Ohio 3.0 4.0 5.0

Texas 6.0 7.0 8.0

Oregon 9.0 10.0 11.0

將他們相加后抽高,會(huì)返回一個(gè)新的DataFrame,其索引和列為原來的那兩個(gè)DataFrame的并集:

In [10]: df1+df2

Out[10]:

b c d e

Colorado NaN NaN NaN NaN

Ohio 3.0 NaN 6.0 NaN

Oregon NaN NaN NaN NaN

Texas 9.0 NaN 12.0 NaN

Utah NaN NaN NaN NaN

5.2.4.1在算術(shù)方法中填充值

在不同索引的對(duì)象進(jìn)行算術(shù)運(yùn)算時(shí)透绩,你可能希望當(dāng)一個(gè)對(duì)象中某個(gè)軸標(biāo)簽在另一個(gè)對(duì)象張找不到時(shí)填充一個(gè)特殊值:

In [20]: df1=DataFrame(np.arange(12.).reshape((3,4)),columns=list('abcd'))

In [21]: df2=DataFrame(np.arange(20.).reshape((4,5)),columns=list('abcde'))

In [22]: df1

Out[22]:

a b c d

0 0.0 1.0 2.0 3.0

1 4.0 5.0 6.0 7.0

2 8.0 9.0 10.0 11.0

In [23]: df2

Out[23]:

a b c d e

0 0.0 1.0 2.0 3.0 4.0

1 5.0 6.0 7.0 8.0 9.0

2 10.0 11.0 12.0 13.0 14.0

3 15.0 16.0 17.0 18.0 19.0

將他們相加時(shí)翘骂,沒有重疊的位置就會(huì)產(chǎn)生NA值:

In [24]: df1+df2

Out[24]:

a b c d e

0 0.0 2.0 4.0 6.0 NaN

1 9.0 11.0 13.0 15.0 NaN

2 18.0 20.0 22.0 24.0 NaN

3 NaN NaN NaN NaN NaN

使用df1的add方法,傳入df2以及一個(gè)fill_value參數(shù):

In [26]: df1.add(df2,fill_value=0)

Out[26]:

a b c d e

0 0.0 2.0 4.0 6.0 4.0

1 9.0 11.0 13.0 15.0 9.0

2 18.0 20.0 22.0 24.0 14.0

3 15.0 16.0 17.0 18.0 19.0

對(duì)Series或DataFrame重新索引時(shí)帚豪,也可以指定一個(gè)填充值:

In [28]: df1.reindex(columns=df2.columns,fill_value=0)

Out[28]:

a b c d e

0 0.0 1.0 2.0 3.0 0

1 4.0 5.0 6.0 7.0 0

2 8.0 9.0 10.0 11.0 0

表5-7 靈活的算術(shù)方法

方法 說明

add 用于加法(+)的方法

sub 用于減法(-)的方法

div 用于乘法(*)的方法

mul 用于除法(/)的方法

5.2.4.2 DataFrame和Series之間的運(yùn)算

跟NumPy數(shù)組一樣碳竟,DataFrame和Series的=之間的算術(shù)運(yùn)算也是有明確規(guī)定的。

下面來計(jì)算一個(gè)二維數(shù)組與其某行之間的差:

In [29]: arr=np.arange(12.).reshape((3,4))

In [30]: arr

Out[30]:

array([[ 0., 1., 2., 3.],

[ 4., 5., 6., 7.],

[ 8., 9., 10., 11.]])

In [31]: arr[0]

Out[31]: array([ 0., 1., 2., 3.])

In [32]: arr-arr[0]

Out[32]:

array([[ 0., 0., 0., 0.],

[ 4., 4., 4., 4.],

[ 8., 8., 8., 8.]])

上面的運(yùn)算就叫做狸臣,廣播莹桅。

DataFrame和Series之間的運(yùn)算差不多也是如此:

In [33]: frame=DataFrame(np.arange(12.).reshape((4,3)),columns=list('bde'),index=['Utah','Ohio','Texas','Oregon'])

In [34]: series=frame.ix[0]

In [35]: frame

Out[35]:

b d e

Utah 0.0 1.0 2.0

Ohio 3.0 4.0 5.0

Texas 6.0 7.0 8.0

Oregon 9.0 10.0 11.0

In [36]: series

Out[36]:

b 0.0

d 1.0

e 2.0

Name: Utah, dtype: float64

默認(rèn)情況下,DataFrame和Series之間的算術(shù)運(yùn)算符將Series的索引匹配到DataFrame的列烛亦,然后沿著行一直向下廣播:

In [37]: frame - series

Out[37]:

b d e

Utah 0.0 0.0 0.0

Ohio 3.0 3.0 3.0

Texas 6.0 6.0 6.0

Oregon 9.0 9.0 9.0

如果某個(gè)索引值在DataFrame的列或Series的索引中找不到诈泼,則參與運(yùn)算的兩個(gè)對(duì)象就會(huì)被重新索引以形成并集:

In [38]: series2=Series(range(3),index=['b','e','f'])

In [39]: frame+series2

Out[39]:

b d e f

Utah 0.0 NaN 3.0 NaN

Ohio 3.0 NaN 6.0 NaN

Texas 6.0 NaN 9.0 NaN

Oregon 9.0 NaN 12.0 NaN

如果你希望匹配行且在列上廣播,則必須使用算術(shù)運(yùn)算方法:

In [40]: series3=frame['d']

In [41]: frame

Out[41]:

b d e

Utah 0.0 1.0 2.0

Ohio 3.0 4.0 5.0

Texas 6.0 7.0 8.0

Oregon 9.0 10.0 11.0

In [42]: series3

Out[42]:

Utah 1.0

Ohio 4.0

Texas 7.0

Oregon 10.0

Name: d, dtype: float64

In [43]: frame.sub(series3,axis=0)

Out[43]:

b d e

Utah -1.0 0.0 1.0

Ohio -1.0 0.0 1.0

Texas -1.0 0.0 1.0

Oregon -1.0 0.0 1.0

傳入的軸號(hào)就是希望匹配的軸此洲。

5.2.5函數(shù)應(yīng)用和映射

Numpy的ufuncs(元素級(jí)數(shù)組方法)也可以用于操作pandas對(duì)象:

In [44]: frame=DataFrame(np.random.randn(4,3),columns=list('bde'),index=['Utah','Ohio','Texas','Oregon'])

In [45]: frame

Out[45]:

b d e

Utah -0.172344 1.823441 -0.067380

Ohio -0.338604 -0.189082 -0.145676

Texas 1.310289 -0.518146 -0.231740

Oregon -1.880954 -0.400772 0.228320

In [46]: np.abs(frame)

Out[46]:

b d e

Utah 0.172344 1.823441 0.067380

Ohio 0.338604 0.189082 0.145676

Texas 1.310289 0.518146 0.231740

Oregon 1.880954 0.400772 0.228320

另一個(gè)常見的操作厂汗,將函數(shù)應(yīng)用到由各列或行所形成的一維數(shù)組上。DataFrame的apply方法即可實(shí)現(xiàn)此功能:

In [47]: f=lambda x:x.max() - x.min()

In [48]: frame.apply(f)

Out[48]:

b 3.191243

d 2.341587

e 0.460059

dtype: float64

In [49]: frame.apply(f,axis=1)

Out[49]:

Utah 1.995785

Ohio 0.192928

Texas 1.828435

Oregon 2.109274

dtype: float64

除標(biāo)量外呜师,傳遞給apply的函數(shù)還可以返回由多個(gè)值組成的Series:

In [52]: def f(x):

...: return Series([x.min(),x.max()],index=['min','max'])

...:

In [53]: frame.apply(f)

Out[53]:

b d e

min -1.880954 -0.518146 -0.23174

max 1.310289 1.823441 0.22832

此外娶桦,元素級(jí)的python函數(shù)也是可以用的。

假如想得到frame中各個(gè)浮點(diǎn)數(shù)的格式化字符串,使用applymap即可:

In [54]: format=lambda x:'%.2f' %x

In [55]: frame.applymap(format)

Out[55]:

b d e

Utah -0.17 1.82 -0.07

Ohio -0.34 -0.19 -0.15

Texas 1.31 -0.52 -0.23

Oregon -1.88 -0.40 0.23

之所以叫做applymap衷畦,是因?yàn)镾eries有一個(gè)用于應(yīng)用元素級(jí)函數(shù)的map的方法:

In [56]: frame['e'].map(format)

Out[56]:

Utah -0.07

Ohio -0.15

Texas -0.23

Oregon 0.23

Name: e, dtype: object

5.2.6排序和排名

根據(jù)條件對(duì)數(shù)據(jù)集排序也是一種重要的內(nèi)置運(yùn)算栗涂。要對(duì)行或列索引進(jìn)行排序(按字典順序),可以使用sort_index方法祈争,它將返回一個(gè)已經(jīng)排序的新對(duì)象:

In [57]: obj=Series(range(4),index=['d','a','b','c'])

In [58]: obj.sort_index()

Out[58]:

a 1

b 2

c 3

d 0

dtype: int64

而對(duì)于DataFrame斤程,則可以根據(jù)任意一個(gè)軸上的索引進(jìn)行排序:

In [59]: frame=DataFrame(np.arange(8).reshape((2,4)),index=['three','one'],columns=['d','a','b','c'])

In [60]: frame.sort_index()

Out[60]:

d a b c

one 4 5 6 7

three 0 1 2 3

In [61]: frame.sort_index(axis=1)

Out[61]:

a b c d

three 1 2 3 0

one 5 6 7 4

數(shù)據(jù)默認(rèn)是按升序排列的,但也可以降序排序:

In [64]: frame.sort_index(axis=1,ascending=False)

Out[64]:

d c b a

three 0 3 2 1

one 4 7 6 5

若要按值對(duì)Series進(jìn)行排序菩混,可以使用order方法:

In [65]: obj=Series([4,7,-3,2])

In [66]: obj.order()

Out[66]:

2 -3

3 2

0 4

1 7

dtype: int64

在排序的時(shí)候忿墅,缺失值默認(rèn)都會(huì)被放在了Series的末尾:

In [67]: obj=Series([4,np.nan,7,np.nan,-3,2])

In [68]: obj.order()

Out[68]:

4 -3.0

5 2.0

0 4.0

2 7.0

1 NaN

3 NaN

dtype: float64

在DataFrame上,你可能希望根據(jù)一個(gè)或多個(gè)列中的值進(jìn)行排序沮峡。將一個(gè)或多個(gè)列的名字傳遞給by選項(xiàng)即可達(dá)到該目的:

In [69]: frame=DataFrame({'b':[4,7,-3,2],'a':[0,1,0,1]})

In [70]: frame

Out[70]:

a b

0 0 4

1 1 7

2 0 -3

3 1 2

In [71]: frame.sort_index(by='b')

Out[71]:

a b

2 0 -3

3 1 2

0 0 4

1 1 7

要根據(jù)多個(gè)列進(jìn)行排序疚脐,傳入名稱的列表即可:

In [73]: frame.sort_index(by=['a','b'])

Out[73]:

a b

2 0 -3

0 0 4

3 1 2

1 1 7

排名(ranking)跟排序關(guān)系密切,且會(huì)增設(shè)一個(gè)排名值(從1開始邢疙,一直到數(shù)組中有效數(shù)據(jù)的數(shù)量)棍弄,跟numpy.argsort產(chǎn)生的間接排序索引差不多,只不過它可以根據(jù)某種規(guī)則破壞平級(jí)關(guān)系疟游。

下面介紹Series和DataFrame的rank方法呼畸。默認(rèn)下:rank是通過“為各組分配一個(gè)平均排名”的方式來破壞平級(jí)關(guān)系。

In [75]: obj=Series([7,-5,7,4,2,0,4])

In [76]: obj.rank()

Out[76]:

0 6.5

1 1.0

2 6.5

3 4.5

4 3.0

5 2.0

6 4.5

dtype: float64

也可以根據(jù)值在原數(shù)據(jù)中出現(xiàn)的順序給出排名:

In [77]: obj.rank(method='first')

Out[77]:

0 6.0

1 1.0

2 7.0

3 4.0

4 3.0

5 2.0

6 5.0

dtype: float64

也可以按降序進(jìn)行排名:

In [78]: obj.rank(ascending=False,method='max')

Out[78]:

0 2.0

1 7.0

2 2.0

3 4.0

4 5.0

5 6.0

6 4.0

dtype: float64

表5-8 列出了所有用于破壞平級(jí)關(guān)系的method選項(xiàng)颁虐。DataFrame可以在行或列上計(jì)算排名:

In [79]: frame=DataFrame({'b':[4.3,7,-3,2],'a':[0,1,0,1],'c':[-2,5,8,-2.5]})

In [80]: frame

Out[80]:

a b c

0 0 4.3 -2.0

1 1 7.0 5.0

2 0 -3.0 8.0

3 1 2.0 -2.5

In [81]: frame.rank(axis=1)

Out[81]:

a b c

0 2.0 3.0 1.0

1 1.0 3.0 2.0

2 2.0 1.0 3.0

3 2.0 3.0 1.0

表5-8 :排名時(shí)用于破壞平級(jí)關(guān)系的method選項(xiàng)

method 說明

‘a(chǎn)verage’ 默認(rèn):在相等分組中蛮原,為各個(gè)值分配平均排‘’

‘min’ 使用整個(gè)分組的最小排名

‘max’ 使用整個(gè)分組的最大排名

‘first’ 按值在原始數(shù)據(jù)中的出現(xiàn)順序分配排名

5.2.7帶有重復(fù)的軸索引

我們看看下面這個(gè)簡單的帶有重復(fù)索引值的Series:

In [82]: obj=Series(range(5),index=['a','a','b','b','c'])

In [83]: obj

Out[83]:

a 0

a 1

b 2

b 3

c 4

dtype: int64

索引的is_unique屬性可以告訴你他的值是否是唯一的:

In [84]: obj.index.is_unique

Out[84]: False

對(duì)于重復(fù)的索引,數(shù)據(jù)選取的行為將會(huì)有些不同聪廉。如果某個(gè)索引對(duì)應(yīng)的多個(gè)值瞬痘,則返回一個(gè)Series,而對(duì)應(yīng)單個(gè)值板熊,則返回一個(gè)標(biāo)量:

In [85]: obj['a']

Out[85]:

a 0

a 1

dtype: int64

In [86]: obj['c']

Out[86]: 4

對(duì)DataFrame的行進(jìn)行索引時(shí)候也是如此:

In [87]: df=DataFrame(np.random.randn(4,3),index=['a','a','b','b'])

In [88]: df

Out[88]:

0 1 2

a 0.056598 1.592208 -0.576368

a 0.842511 -0.085418 0.818032

b 1.347421 -0.239196 -0.543597

b -0.598395 0.966395 0.285722

In [89]: df.ix['b']

Out[89]:

0 1 2

b 1.347421 -0.239196 -0.543597

b -0.598395 0.966395 0.285722

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末框全,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子干签,更是在濱河造成了極大的恐慌津辩,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件容劳,死亡現(xiàn)場離奇詭異喘沿,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)竭贩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門蚜印,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人留量,你說我怎么就攤上這事窄赋∮炊” “怎么了?”我有些...
    開封第一講書人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵忆绰,是天一觀的道長浩峡。 經(jīng)常有香客問我,道長错敢,這世上最難降的妖魔是什么翰灾? 我笑而不...
    開封第一講書人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮稚茅,結(jié)果婚禮上纸淮,老公的妹妹穿的比我還像新娘。我一直安慰自己亚享,他們只是感情好萎馅,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著虹蒋,像睡著了一般。 火紅的嫁衣襯著肌膚如雪飒货。 梳的紋絲不亂的頭發(fā)上魄衅,一...
    開封第一講書人閱讀 51,125評(píng)論 1 297
  • 那天,我揣著相機(jī)與錄音塘辅,去河邊找鬼晃虫。 笑死,一個(gè)胖子當(dāng)著我的面吹牛扣墩,可吹牛的內(nèi)容都是我干的哲银。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼呻惕,長吁一口氣:“原來是場噩夢啊……” “哼荆责!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起亚脆,我...
    開封第一講書人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤做院,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后濒持,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體键耕,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年柑营,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了屈雄。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡官套,死狀恐怖酒奶,靈堂內(nèi)的尸體忽然破棺而出蚁孔,到底是詐尸還是另有隱情,我是刑警寧澤讥蟆,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布勒虾,位于F島的核電站,受9級(jí)特大地震影響瘸彤,放射性物質(zhì)發(fā)生泄漏修然。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一质况、第九天 我趴在偏房一處隱蔽的房頂上張望愕宋。 院中可真熱鬧,春花似錦结榄、人聲如沸中贝。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽邻寿。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背谈息。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來泰國打工漾抬, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親段磨。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

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