利用python進行數據分析之數據規整化(二)

7.3 數據轉換

還有一個重要操作就是 過濾、清理、以及其他的轉換工作。

7.3.1 移除重復數據

DataFrame有時候會出現重復的行:

In [27]: data=DataFrame({'k1':['one']*3+['two']*4,'k2':[1,1,2,3,3,4,4]})

In [28]: data

Out[28]:

k1 k2

0 one 1

1 one 1

2 one 2

3 two 3

4 two 3

5 two 4

6 two 4

DataFrame的duplicated方法會返回一個布爾型的Series:

In [29]: data.duplicated()

Out[29]:

0 False

1 True

2 False

3 False

4 True

5 False

6 True

dtype: bool

我們使用drop_duplicates()方法,用于移除重復行的DataFrame:

In [31]: data.drop_duplicates()

Out[31]:

k1 k2

0 one 1

2 one 2

3 two 3

5 two 4

In [32]: data['v1']=range(7)

In [33]: data

Out[33]:

k1 k2 v1

0 one 1 0

1 one 1 1

2 one 2 2

3 two 3 3

4 two 3 4

5 two 4 5

6 two 4 6

我們還可以對列進行指定去除重復值,

In [35]: data.drop_duplicates(['k1'])

Out[35]:

k1 k2 v1

0 one 1 0

3 two 3 3

In [36]: data.drop_duplicates(['k1','k2'])

Out[36]:

k1 k2 v1

0 one 1 0

2 one 2 2

3 two 3 3

5 two 4 5

duplicated和drop_duplicates 默認保留的的是第一個出現的值的組合,傳入的take_last=True就可以保留最后一個。

In [37]: data.drop_duplicates(['k1','k2'],take_last=True)

__main__:1: FutureWarning: the take_last=True keyword is deprecated, use keep='last' instead

Out[37]:

k1 k2 v1

1 one 1 1

2 one 2 2

4 two 3 4

6 two 4 6

7.3.2 利用函數或映射進行數據轉換

有時候我們需要給數據里面添加一列。可能希望根據數組、Series、DataFrame列中的值來實現轉換工作。

In [2]: import numpy as np

...: import pandas as pd

...: from pandas import Series,DataFrame

...:

In [3]: data = DataFrame({'food':['bacon','pulled pork','bacon','Pastrami','corned beef','Bacon','pastrami',

...:? ? 'honey ham','nova lox'],'ounces':[4,3,12,6,7.5,8,3,5,6]})

In [4]: data

Out[4]:

food? ounces

0? ? ? ? bacon? ? 4.0

1? pulled pork? ? 3.0

2? ? ? ? bacon? ? 12.0

3? ? Pastrami? ? 6.0

4? corned beef? ? 7.5

5? ? ? ? Bacon? ? 8.0

6? ? pastrami? ? 3.0

7? ? honey ham? ? 5.0

8? ? nova lox? ? 6.0

我們想添加這一列映射,Series的map方法可接受一個函數或者含有映射關系的字典對象。

仔細觀察數據,我們發現,有些單詞的字母大寫了,需要進行大小寫轉換,否則無法添映射。

In [5]: meat_to_animal = {

...:? ? 'bacon':'pig',

...:? ? 'pulled pork':'pig',

...:? ? 'pastrami':'cow',

...:? ? 'corned beef':'cow',

...:? ? 'honey ham':'pig',

...:? ? 'nova lox':'salmon'

...: }

In [8]: data['animal']=data['food'].map(str.lower).map(meat_to_animal)

In [9]: data

Out[9]:

food? ounces? animal

0? ? ? ? bacon? ? 4.0? ? pig

1? pulled pork? ? 3.0? ? pig

2? ? ? ? bacon? ? 12.0? ? pig

3? ? Pastrami? ? 6.0? ? cow

4? corned beef? ? 7.5? ? cow

5? ? ? ? Bacon? ? 8.0? ? pig

6? ? pastrami? ? 3.0? ? cow

7? ? honey ham? ? 5.0? ? pig

8? ? nova lox? ? 6.0? salmon

In [10]: data['food'].map(str.lower)

Out[10]:

0? ? ? ? ? bacon

1? ? pulled pork

2? ? ? ? ? bacon

3? ? ? pastrami

4? ? corned beef

5? ? ? ? ? bacon

6? ? ? pastrami

7? ? ? honey ham

8? ? ? nova lox

Name: food, dtype: object

或者我們可以這樣做:

In [11]: data['food'].map(lambda x:meat_to_animal[x.lower()])

Out[11]:

0? ? ? pig

1? ? ? pig

2? ? ? pig

3? ? ? cow

4? ? ? cow

5? ? ? pig

6? ? ? cow

7? ? ? pig

8? ? salmon

Name: food, dtype: object

In [12]: lambda x:meat_to_animal[x.lower()]

Out[12]: >


彩蛋:關于lambda函數的復習

在python中,對匿名函數提供了有限支持。還是以map()函數為例,計算 f(x)=x2 時,除了定義一個f(x)的函數外,還可以直接傳入匿名函數:

>>> map(lambda x:x*x,[1,2,3,4,5,6,7,8,9])

[1, 4, 9, 16, 25, 36, 49, 64, 81]

lambda x:x*x

等價于:

def f(x):

return x*x

關鍵字lambda表示匿名參數,冒號前面的x表示函數參數。


7.3.3 替換值

利用fillna的方法填充缺失數據可以看做替換的一種特殊情況。

replace和map都可以用于修改對象的子集。實際上replace簡單、靈活。

In [13]: data=Series([1.,-999.,2.,-999.,-1000.,3.])

In [14]: data

Out[14]:

0? ? ? 1.0

1? ? -999.0

2? ? ? 2.0

3? ? -999.0

4? -1000.0

5? ? ? 3.0

dtype: float64

#-999替換為缺失值

In [15]: data.replace(-999,np.nan)

Out[15]:

0? ? ? 1.0

1? ? ? NaN

2? ? ? 2.0

3? ? ? NaN

4? -1000.0

5? ? ? 3.0

dtype: float64

#傳入由替換值組成的列表以及一個缺失值

In [16]: data.replace([-999,-1000],np.nan)

Out[16]:

0? ? 1.0

1? ? NaN

2? ? 2.0

3? ? NaN

4? ? NaN

5? ? 3.0

dtype: float64

In [17]: data.replace([-999,-1000],[np.nan,0])

Out[17]:

0? ? 1.0

1? ? NaN

2? ? 2.0

3? ? NaN

4? ? 0.0

5? ? 3.0

dtype: float64

#也可以傳入字典

In [18]: data.replace({-999:np.nan,-1000:0})

Out[18]:

0? ? 1.0

1? ? NaN

2? ? 2.0

3? ? NaN

4? ? 0.0

5? ? 3.0

dtype: float64

7.3.4 重命名軸索引

軸標簽可以通過函數或映射的關系進行轉換,得到一個新對象。為了不必新建一個數據結構,軸可以修改。

In [19]: data = DataFrame(np.arange(12).reshape((3,4)),index = ['Ohio','Colorado','New York'],

...:? ? columns = ['one','two','three','four'])

In [20]: data

Out[20]:

one? two? three? four

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

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

New York? ? 8? ? 9? ? 10? ? 11

#和Series相同,軸標簽也有一個map方法:

In [21]: data.index.map(str.upper)

Out[21]: array(['OHIO', 'COLORADO', 'NEW YORK'], dtype=object)

#賦值給index,對DataFrame進行修改

In [22]: data.index=data.index.map(str.upper)

In [23]: data

Out[23]:

one? two? three? four

OHIO? ? ? ? 0? ? 1? ? ? 2? ? 3

COLORADO? ? 4? ? 5? ? ? 6? ? 7

NEW YORK? ? 8? ? 9? ? 10? ? 11

#創建數據集的轉行版

In [24]: data.rename(index=str.title,columns=str.upper)

Out[24]:

ONE? TWO? THREE? FOUR

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

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

New York? ? 8? ? 9? ? 10? ? 11

In [25]: index=str.title

In [26]: index

Out[26]:

#rename可以結合字典對象實現部分軸標簽的更新,

In [27]: data.rename(index={'OHIO':'INDIANA'},columns={'three':'peekaboo'})

Out[27]:

one? two? peekaboo? four

INDIANA? ? 0? ? 1? ? ? ? 2? ? 3

COLORADO? ? 4? ? 5? ? ? ? 6? ? 7

NEW YORK? ? 8? ? 9? ? ? ? 10? ? 11

rename可以實現:復制DataFrame并對其進行索引和列標簽進行賦值。對希望修改的數據集,傳入參數inplace=True 即可。

#總是返回DataFrame的引用

In [28]: _=data.rename(index={'OHIO':'INDIANA'},inplace=True)

In [29]: data

Out[29]:

one? two? three? four

INDIANA? ? 0? ? 1? ? ? 2? ? 3

COLORADO? ? 4? ? 5? ? ? 6? ? 7

NEW YORK? ? 8? ? 9? ? 10? ? 11

In [30]: _

Out[30]:

one? two? three? four

INDIANA? ? 0? ? 1? ? ? 2? ? 3

COLORADO? ? 4? ? 5? ? ? 6? ? 7

NEW YORK? ? 8? ? 9? ? 10? ? 11

7.3.5 離散化和面元劃分

為了便于分析,離散化的數據常常會被離散化拆分為“面元(bin)”。

In [31]: ages = [20,22,25,27,21,23,37,31,61,45,41,32]

把數據拆分為(18,25)(25,35)(35,60)(60,100)這幾各面元,可以使用pandas的cut函數,

In [32]: bins=[18,25,35,60,100]

In [33]: cats=pd.cut(ages,bins)

#返回了一個特殊的Categories 對象,看做是一組表示面元名稱的字符串。

In [34]: cats

Out[34]:

[(18, 25], (18, 25], (18, 25], (25, 35], (18, 25], ..., (25, 35], (60, 100], (35, 60], (35, 60], (25, 35]]

Length: 12

Categories (4, object): [(18, 25] < (25, 35] < (35, 60] < (60, 100]]

In [37]: pd.value_counts(cats)

Out[37]:

(18, 25] 5

(35, 60] 3

(25, 35] 3

(60, 100] 1

dtype: int64

#可以通過right=Flase來進行修改區間的開端和閉端

In [39]: cats=pd.cut(ages,bins,right=False)

In [40]: cats

Out[40]:

[[18, 25), [18, 25), [25, 35), [25, 35), [18, 25), ..., [25, 35), [60, 100), [35, 60), [35, 60), [25, 35)]

Length: 12

Categories (4, object): [[18, 25) < [25, 35) < [35, 60) < [60, 100)]

#自己設置面元名稱,將labels選項設置為一個列表或數組

In [41]: group_names=['Youth','YoungAdult','MidddleAged','Senior']

In [42]: pd.cut(ages,bins,labels=group_names)

Out[42]:

[Youth, Youth, Youth, YoungAdult, Youth, ..., YoungAdult, Senior, MidddleAged, MidddleAged, YoungAdult]

Length: 12

Categories (4, object): [Youth < YoungAdult < MidddleAged < Senior]

#如果cut傳入的面元的數量沒有確切的邊界,則會根據數據的最小值和最大值計算等面元。

In [43]: data=np.random.rand(20)

In [44]: data

Out[44]:

array([ 0.18052819, 0.30816514, 0.12574293, ..., 0.69175506,

0.46870553, 0.56315958])

#將數據均勻的分布為4組,小數精度保留3位

In [45]: pd.cut(data,4,precision=3)

Out[45]:

[(0.0834, 0.304], (0.304, 0.523], (0.0834, 0.304], (0.523, 0.742], (0.304, 0.523], ..., (0.0834, 0.304], (0.304, 0.523], (0.523, 0.742], (0.304, 0.523], (0.523, 0.742]]

Length: 20

Categories (4, object): [(0.0834, 0.304] < (0.304, 0.523] < (0.523, 0.742] < (0.742, 0.961]]

In [46]: pd.cut(data,4,precision=2)

Out[46]:

[(0.083, 0.3], (0.3, 0.52], (0.083, 0.3], (0.52, 0.74], (0.3, 0.52], ..., (0.083, 0.3], (0.3, 0.52], (0.52, 0.74], (0.3, 0.52], (0.52, 0.74]]

Length: 20

Categories (4, object): [(0.083, 0.3] < (0.3, 0.52] < (0.52, 0.74] < (0.74, 0.96]]

#qcut使用的是樣本的分位數,可以得到基本大小相等的面元

#正態分布

In [47]: data=np.random.randn(100)

#按四分位數進行切割

In [48]: cats=pd.cut(data,4)

In [49]: cats

Out[49]:

[(-0.824, 0.467], (-0.824, 0.467], (-0.824, 0.467], (-2.121, -0.824], (-0.824, 0.467], ..., (-0.824, 0.467], (-0.824, 0.467], (-0.824, 0.467], (-2.121, -0.824], (-2.121, -0.824]]

Length: 100

Categories (4, object): [(-2.121, -0.824] < (-0.824, 0.467] < (0.467, 1.759] < (1.759, 3.0507]]

In [50]: cats=pd.cut(data,4,precision=2)

In [51]: cats

Out[51]:

[(-0.82, 0.47], (-0.82, 0.47], (-0.82, 0.47], (-2.12, -0.82], (-0.82, 0.47], ..., (-0.82, 0.47], (-0.82, 0.47], (-0.82, 0.47], (-2.12, -0.82], (-2.12, -0.82]]

Length: 100

Categories (4, object): [(-2.12, -0.82] < (-0.82, 0.47] < (0.47, 1.76] < (1.76, 3.051]]

In [53]: pd.value_counts(cats)

Out[53]:

(-0.82, 0.47] 50

(0.47, 1.76] 24

(-2.12, -0.82] 21

(1.76, 3.051] 5

dtype: int64

In [54]: pd.qcut(data,[0,0.1,0.5,0.9,1.])

Out[54]:

[(-1.239, -0.171], (-1.239, -0.171], (-0.171, 1.399], (-1.239, -0.171], (-0.171, 1.399], ..., (-1.239, -0.171], (-0.171, 1.399], (-1.239, -0.171], [-2.116, -1.239], (-1.239, -0.171]]

Length: 100

Categories (4, object): [[-2.116, -1.239] < (-1.239, -0.171] < (-0.171, 1.399] < (1.399, 3.0507]]

#可以設置自定義的分位數

In [55]: df=pd.qcut(data,[0,0.1,0.5,0.9,1.])

In [56]: pd.value_counts(df)

Out[56]:

(-0.171, 1.399] 40

(-1.239, -0.171] 40

(1.399, 3.0507] 10

[-2.116, -1.239] 10

dtype: int64

7.3.6 檢測和過濾異常值

異常值的過濾或變換運算在很大程度上就是數組運算。

In [58]: np.random.seed(12345)

In [59]: data=DataFrame(np.random.randn(1000,4))

In [60]: data

Out[60]:

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

0? -0.204708? 0.478943 -0.519439 -0.555730

1? ? 1.965781? 1.393406? 0.092908? 0.281746

2? ? 0.769023? 1.246435? 1.007189 -1.296221

3? ? 0.274992? 0.228913? 1.352917? 0.886429

4? -2.001637 -0.371843? 1.669025 -0.438570

..? ? ? ? ...? ? ? ...? ? ? ...? ? ? ...

995? 1.089085? 0.251232 -1.451985? 1.653126

996 -0.478509 -0.010663 -1.060881 -1.502870

997 -1.946267? 1.013592? 0.037333? 0.133304

998 -1.293122 -0.322542 -0.782960 -0.303340

999? 0.089987? 0.292291? 1.177706? 0.882755

[1000 rows x 4 columns]

In [61]: data.describe()

Out[61]:

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

count? 1000.000000? 1000.000000? 1000.000000? 1000.000000

mean? ? -0.067684? ? 0.067924? ? 0.025598? ? -0.002298

std? ? ? 0.998035? ? 0.992106? ? 1.006835? ? 0.996794

min? ? ? -3.428254? ? -3.548824? ? -3.184377? ? -3.745356

25%? ? ? -0.774890? ? -0.591841? ? -0.641675? ? -0.644144

50%? ? ? -0.116401? ? 0.101143? ? 0.002073? ? -0.013611

75%? ? ? 0.616366? ? 0.780282? ? 0.680391? ? 0.654328

max? ? ? 3.366626? ? 2.653656? ? 3.260383? ? 3.927528

#找出某列中絕對值大小超過3的值

In [62]: col=data[3]

In [63]: col[np.abs(col)>3]

Out[63]:

97? ? 3.927528

305? -3.399312

400? -3.745356

Name: 3, dtype: float64

#找出數據中全部絕對值大小超過3的值,使用any方法

In [65]: data[(np.abs(data)>3).any(1)]

Out[65]:

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

5? -0.539741? 0.476985? 3.248944 -1.021228

97? -0.774363? 0.552936? 0.106061? 3.927528

102 -0.655054 -0.565230? 3.176873? 0.959533

305 -2.315555? 0.457246 -0.025907 -3.399312

324? 0.050188? 1.951312? 3.260383? 0.963301

400? 0.146326? 0.508391 -0.196713 -3.745356

499 -0.293333 -0.242459 -3.056990? 1.918403

523 -3.428254 -0.296336 -0.439938 -0.867165

586? 0.275144? 1.179227 -3.184377? 1.369891

808 -0.362528 -3.548824? 1.553205 -2.186301

900? 3.366626 -2.372214? 0.851010? 1.332846

#可以將置限制在(-3,3)的區間內

#np.sign 這個ufunc返回的是一個由1和-1組成的數組,表示原始值的符號

In [66]: data[(np.abs(data)>3)]=np.sign(data)*3

In [67]: data.describe()

Out[67]:

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

count? 1000.000000? 1000.000000? 1000.000000? 1000.000000

mean? ? -0.067623? ? 0.068473? ? 0.025153? ? -0.002081

std? ? ? 0.995485? ? 0.990253? ? 1.003977? ? 0.989736

min? ? ? -3.000000? ? -3.000000? ? -3.000000? ? -3.000000

25%? ? ? -0.774890? ? -0.591841? ? -0.641675? ? -0.644144

50%? ? ? -0.116401? ? 0.101143? ? 0.002073? ? -0.013611

75%? ? ? 0.616366? ? 0.780282? ? 0.680391? ? 0.654328

max? ? ? 3.000000? ? 2.653656? ? 3.000000? ? 3.000000

7.3.7 排列(permutation)和隨機采樣

利用numpy.random.permutation可以對Series和DataFrame進行排列

通過需要排列的軸的長度調用permutation,會產生一個表示新順序的整數數組。

In [68]: df=DataFrame(np.arange(5*4).reshape(5,4))

In [69]: sampler=(np.random.permutation(5))

In [70]: df

Out[70]:

0? 1? 2? 3

0? 0? 1? 2? 3

1? 4? 5? 6? 7

2? 8? 9? 10? 11

3? 12? 13? 14? 15

4? 16? 17? 18? 19

In [71]: sampler

Out[71]: array([1, 0, 2, 3, 4])

#在基于ix的索引操作或take函數中使用該數組了

In [73]: df.take(sampler)

Out[73]:

0? 1? 2? 3

1? 4? 5? 6? 7

0? 0? 1? 2? 3

2? 8? 9? 10? 11

3? 12? 13? 14? 15

4? 16? 17? 18? 19

#可以看到,直接這樣切片,報錯了

In [75]: df.take(np.random.permutation(len(df)[:3]))

Traceback (most recent call last):

File "", line 1, in

df.take(np.random.permutation(len(df)[:3]))

TypeError: 'int' object has no attribute '__getitem__'

In [76]: len(df)

Out[76]: 5

In [77]: len(df)[:3]

Traceback (most recent call last):

File "", line 1, in

len(df)[:3]

TypeError: 'int' object has no attribute '__getitem__'

#從permutation返回的數組中切片出前k個元素,其中k為期望的子集大小。

In [85]: df.take(np.random.permutation(np.arange(len(df))[:3]))

Out[85]:

0? 1? 2? 3

1? 4? 5? 6? 7

0? 0? 1? 2? 3

2? 8? 9? 10? 11

In [87]: np.arange(len(df))[:3]

Out[87]: array([0, 1, 2])

#In [89]: bag=np.array([5,7,-1,6,4])

#要通過替換的方式生產樣本,最快的方式是通過np.random.randint得到一組隨機整數

In [91]: sampler=np.random.randint(0,len(bag),size=10)

In [92]: sampler

Out[92]: array([4, 4, 4, 2, 2, 2, 0, 3, 0, 4])

In [95]: sampler=np.random.randint(0,5,size=10)

In [96]: sampler

Out[96]: array([1, 2, 0, 4, 4, 4, 3, 4, 2, 2])

In [97]: draws=bag.take(sampler)

In [98]: draws

Out[98]: array([ 7, -1,? 5,? 4,? 4,? 4,? 6,? 4, -1, -1])

7.3.8 計算指標/啞變量

另一種常用于統計建模或機器學習的轉換方式:將分類變量(categorical variable)轉換為“啞變量矩陣(dummy matrix)”或“指標矩陣(indicator matrix)”。

若DataFrame的某一列含有k不同的值,則可以派生出一個k列矩陣或DataFrame(其值全為0或1)。

pandas中的get_dummies函數可以實現上面的功能。

In [15]: mnames=['movie_id','title','genres']

In [16]: movies=pd.read_table('F:\pydata-book-master\ch02\movielens\movies.dat',sep='::',header=None,names=mnames)

__main__:1: ParserWarning: Falling back to the 'python' engine because the 'c' engine does not support regex separators (separators > 1 char and different from '\s+' are interpreted as regex); you can avoid this warning by specifying engine='python'.

#觀察一下數據最前面的10行

In [17]: movies[:10]

Out[17]:

movie_id? ? ? ? ? ? ? ? ? ? ? ? ? ? ? title? ? ? ? ? ? ? ? ? ? ? ? genres

0? ? ? ? 1? ? ? ? ? ? ? ? ? ? Toy Story (1995)? Animation|Children's|Comedy

1? ? ? ? 2? ? ? ? ? ? ? ? ? ? ? Jumanji (1995)? Adventure|Children's|Fantasy

2? ? ? ? 3? ? ? ? ? ? Grumpier Old Men (1995)? ? ? ? ? ? ? ? Comedy|Romance

3? ? ? ? 4? ? ? ? ? ? Waiting to Exhale (1995)? ? ? ? ? ? ? ? ? Comedy|Drama

4? ? ? ? 5? Father of the Bride Part II (1995)? ? ? ? ? ? ? ? ? ? ? ? Comedy

5? ? ? ? 6? ? ? ? ? ? ? ? ? ? ? ? Heat (1995)? ? ? ? Action|Crime|Thriller

6? ? ? ? 7? ? ? ? ? ? ? ? ? ? ? Sabrina (1995)? ? ? ? ? ? ? ? Comedy|Romance

7? ? ? ? 8? ? ? ? ? ? ? ? Tom and Huck (1995)? ? ? ? ? Adventure|Children's

8? ? ? ? 9? ? ? ? ? ? ? ? Sudden Death (1995)? ? ? ? ? ? ? ? ? ? ? ? Action

9? ? ? ? 10? ? ? ? ? ? ? ? ? ? GoldenEye (1995)? ? Action|Adventure|Thriller

[3873 rows x 3 columns]

#觀察一下數據最后的5行

In [21]: movies[-5:]

Out[21]:

movie_id? ? ? ? ? ? ? ? ? ? ? title? ? ? ? ? genres

3878? ? ? 3948? ? Meet the Parents (2000)? ? ? ? ? Comedy

3879? ? ? 3949? Requiem for a Dream (2000)? ? ? ? ? Drama

3880? ? ? 3950? ? ? ? ? ? Tigerland (2000)? ? ? ? ? Drama

3881? ? ? 3951? ? Two Family House (2000)? ? ? ? ? Drama

3882? ? ? 3952? ? ? Contender, The (2000)? Drama|Thriller

#要為每個genre添加指標變量

In [22]: genre_iter=(set(x.split('|')) for x in movies.genres)

#從數據中抽取出不同的genre值,使用set.union,并排序

In [23]: genres=sorted(set.union(*genre_iter))

#從一個全零的DataFrame開始構建指標DataFrame

In [24]: dummies=DataFrame(np.zeros((len(movies),len(genres))),columns=genres)

In [25]: len(movies)

Out[25]: 3883

In [26]: len(genres)

Out[26]: 18

#迭代每一部電影并將dummies設為1

In [27]: for i,gen in enumerate(movies.genres):

...:? ? dummies.ix[i,gen.split('|')]=1

...:

#將dummies與movies兩個數據集合并起來

In [28]: movies_windic=movies.join(dummies.add_prefix('Genre_'))

In [29]: movies_windic.ix[0]

Out[29]:

movie_id? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 1

title? ? ? ? ? ? ? ? ? ? ? ? ? Toy Story (1995)

genres? ? ? ? ? ? ? Animation|Children's|Comedy

Genre_Action? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0

Genre_Adventure? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0

Genre_Animation? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 1

Genre_Children's? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 1

Genre_Comedy? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 1

Genre_Crime? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0

Genre_Documentary? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0

Genre_Drama? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0

Genre_Fantasy? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0

Genre_Film-Noir? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0

Genre_Horror? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0

Genre_Musical? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0

Genre_Mystery? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0

Genre_Romance? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0

Genre_Sci-Fi? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0

Genre_Thriller? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0

Genre_War? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0

Genre_Western? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0

Name: 0, dtype: object

In [30]: movies_windic.head()

Out[30]:

movie_id? ? ? ? ? ? ? ? ? ? ? ? ? ? ? title? ? ? ? ? ? ? ? ? ? ? ? genres? \

0? ? ? ? 1? ? ? ? ? ? ? ? ? ? Toy Story (1995)? Animation|Children's|Comedy

1? ? ? ? 2? ? ? ? ? ? ? ? ? ? ? Jumanji (1995)? Adventure|Children's|Fantasy

2? ? ? ? 3? ? ? ? ? ? Grumpier Old Men (1995)? ? ? ? ? ? ? ? Comedy|Romance

3? ? ? ? 4? ? ? ? ? ? Waiting to Exhale (1995)? ? ? ? ? ? ? ? ? Comedy|Drama

4? ? ? ? 5? Father of the Bride Part II (1995)? ? ? ? ? ? ? ? ? ? ? ? Comedy

Genre_Action? Genre_Adventure? Genre_Animation? Genre_Children's? \

0? ? ? ? ? 0.0? ? ? ? ? ? ? 0.0? ? ? ? ? ? ? 1.0? ? ? ? ? ? ? 1.0

1? ? ? ? ? 0.0? ? ? ? ? ? ? 1.0? ? ? ? ? ? ? 0.0? ? ? ? ? ? ? 1.0

2? ? ? ? ? 0.0? ? ? ? ? ? ? 0.0? ? ? ? ? ? ? 0.0? ? ? ? ? ? ? 0.0

3? ? ? ? ? 0.0? ? ? ? ? ? ? 0.0? ? ? ? ? ? ? 0.0? ? ? ? ? ? ? 0.0

4? ? ? ? ? 0.0? ? ? ? ? ? ? 0.0? ? ? ? ? ? ? 0.0? ? ? ? ? ? ? 0.0

Genre_Comedy? Genre_Crime? Genre_Documentary? ? ? ...? ? ? ? Genre_Fantasy? \

0? ? ? ? ? 1.0? ? ? ? ? 0.0? ? ? ? ? ? ? ? 0.0? ? ? ...? ? ? ? ? ? ? ? ? 0.0

1? ? ? ? ? 0.0? ? ? ? ? 0.0? ? ? ? ? ? ? ? 0.0? ? ? ...? ? ? ? ? ? ? ? ? 1.0

2? ? ? ? ? 1.0? ? ? ? ? 0.0? ? ? ? ? ? ? ? 0.0? ? ? ...? ? ? ? ? ? ? ? ? 0.0

3? ? ? ? ? 1.0? ? ? ? ? 0.0? ? ? ? ? ? ? ? 0.0? ? ? ...? ? ? ? ? ? ? ? ? 0.0

4? ? ? ? ? 1.0? ? ? ? ? 0.0? ? ? ? ? ? ? ? 0.0? ? ? ...? ? ? ? ? ? ? ? ? 0.0

Genre_Film-Noir? Genre_Horror? Genre_Musical? Genre_Mystery? Genre_Romance? \

0? ? ? ? ? ? ? 0.0? ? ? ? ? 0.0? ? ? ? ? ? 0.0? ? ? ? ? ? 0.0? ? ? ? ? ? 0.0

1? ? ? ? ? ? ? 0.0? ? ? ? ? 0.0? ? ? ? ? ? 0.0? ? ? ? ? ? 0.0? ? ? ? ? ? 0.0

2? ? ? ? ? ? ? 0.0? ? ? ? ? 0.0? ? ? ? ? ? 0.0? ? ? ? ? ? 0.0? ? ? ? ? ? 1.0

3? ? ? ? ? ? ? 0.0? ? ? ? ? 0.0? ? ? ? ? ? 0.0? ? ? ? ? ? 0.0? ? ? ? ? ? 0.0

4? ? ? ? ? ? ? 0.0? ? ? ? ? 0.0? ? ? ? ? ? 0.0? ? ? ? ? ? 0.0? ? ? ? ? ? 0.0

Genre_Sci-Fi? Genre_Thriller? Genre_War? Genre_Western

0? ? ? ? ? 0.0? ? ? ? ? ? 0.0? ? ? ? 0.0? ? ? ? ? ? 0.0

1? ? ? ? ? 0.0? ? ? ? ? ? 0.0? ? ? ? 0.0? ? ? ? ? ? 0.0

2? ? ? ? ? 0.0? ? ? ? ? ? 0.0? ? ? ? 0.0? ? ? ? ? ? 0.0

3? ? ? ? ? 0.0? ? ? ? ? ? 0.0? ? ? ? 0.0? ? ? ? ? ? 0.0

4? ? ? ? ? 0.0? ? ? ? ? ? 0.0? ? ? ? 0.0? ? ? ? ? ? 0.0

[5 rows x 21 columns]

對于很大的數據,上面這種方式構建的多成員的指標變量會變得很慢,需要編寫一個利用DataFrame內部機制的更低的函數才行。

解決辦法:結合get_dummies和例如cut的離散化函數

In [31]: values=np.random.rand(10)

In [32]: values

Out[32]:

array([ 0.06125988,? 0.71829361,? 0.71451639,? 0.31675263,? 0.43739154,

0.48855471,? 0.87401469,? 0.65884824,? 0.88474031,? 0.57315729])

In [33]: bins=[0,0.2,0.4,0.6,0.8,1]

In [34]: pd.get_dummies(pd.cut(values,bins))

Out[34]:

(0, 0.2]? (0.2, 0.4]? (0.4, 0.6]? (0.6, 0.8]? (0.8, 1]

0? ? ? ? 1? ? ? ? ? 0? ? ? ? ? 0? ? ? ? ? 0? ? ? ? 0

1? ? ? ? 0? ? ? ? ? 0? ? ? ? ? 0? ? ? ? ? 1? ? ? ? 0

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

3? ? ? ? 0? ? ? ? ? 1? ? ? ? ? 0? ? ? ? ? 0? ? ? ? 0

4? ? ? ? 0? ? ? ? ? 0? ? ? ? ? 1? ? ? ? ? 0? ? ? ? 0

5? ? ? ? 0? ? ? ? ? 0? ? ? ? ? 1? ? ? ? ? 0? ? ? ? 0

6? ? ? ? 0? ? ? ? ? 0? ? ? ? ? 0? ? ? ? ? 0? ? ? ? 1

7? ? ? ? 0? ? ? ? ? 0? ? ? ? ? 0? ? ? ? ? 1? ? ? ? 0

8? ? ? ? 0? ? ? ? ? 0? ? ? ? ? 0? ? ? ? ? 0? ? ? ? 1

9? ? ? ? 0? ? ? ? ? 0? ? ? ? ? 1? ? ? ? ? 0? ? ? ? 0

7.4 字符串操作

python對于大部分文本運算都直接做成了字符串的內置方法,對于更為復雜的模式匹配和文本操作,就需要正則表達式了。

7.4.1 字符串對象方法

對于大部分字符串處理應用而言,內置的字符串方法就可以滿足要求。

如,以逗號分隔的字符串可以用split拆分成數段:

In [42]: val='a, b, guido'

In [43]: val.split(',')

Out[43]: ['a', ' b', ' guido']

#split常常結合strip(用于修剪空白符(包括換行符))一起使用

In [44]: pieces=[x.strip() for x in val.split(',')]

In [45]: pieces

Out[45]: ['a', 'b', 'guido']

#利用加法,可以將這些子字符串以雙冒號分隔符的形式連接起來

In [46]: first,second,third=pieces

In [48]: first + '::' + second + '::' +third

Out[48]: 'a::b::guido'

#我們還可以向字符串"::" 的join方法傳入一個列表或元組

In [49]: '::'.join(pieces)

Out[49]: 'a::b::guido'

#檢測子串的利用in關鍵字

In [50]: 'guido' in val

Out[50]: True

In [51]: val.index(',')

Out[51]: 1

In [52]: val.find(':')

Out[52]: -1

#index和find有區別的,找不到字符串就會報錯

In [53]: val.index(':')

Traceback (most recent call last):

File "", line 1, in

val.index(':')

ValueError: substring not found

#指定字符串出現次數

In [54]: val.count(',')

Out[54]: 2

#replace將指定模式替換為另一個模式

In [55]: val.replace(',','::')

Out[55]: 'a:: b:: guido'

In [56]: val.replace(',', '')

Out[56]: 'a b guido'

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,106評論 6 542
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,441評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,211評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,736評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,475評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,834評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,829評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,009評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,559評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,306評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,516評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,038評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,728評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,132評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,443評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,249評論 3 399
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,484評論 2 379

推薦閱讀更多精彩內容