1. 程式人生 > 其它 >DataWhale組隊學習pandas task02

DataWhale組隊學習pandas task02

技術標籤:python資料分析

DataWhale組隊學習pandas task02(下:練習)

這次任務一共有兩個題目:

Ex1:口袋妖怪資料集

現有一份口袋妖怪的資料集,下面進行一些背景說明:

  • #代表全國圖鑑編號,不同行存在相同數字則表示為該妖怪的不同狀態

  • 妖怪具有單屬性和雙屬性兩種,對於單屬性的妖怪,Type2為缺失值

  • Total,HP,Attack,Defense,Sp.Atk,Sp.Def,Speed分別代表種族值、體力、物攻、防禦、特攻、特防、速度,其中種族值為後6項之和

1、對HP,Attack,Defense,Sp.Atk,Sp.Def,Speed進行加總,驗證是否為Total
值。

  • import pandas as pd
    df = pd.read_csv('./data/pokemon.csv')
    df.head()
    
    	#	Name	Type 1	Type 2	Total	HP	Attack	Defense	Sp. Atk	Sp. Def	Speed
    0	1	Bulbasaur	Grass	Poison	318	45	49	49	65	65	45
    1	2	Ivysaur	Grass	Poison	405	60	62	63	80	80	60
    2	3	Venusaur	Grass	Poison	525	80	82	83	100	100	80
    3	3	VenusaurMega Venusaur	Grass	Poison	625	80	100	123	122	120	80
    4	4	Charmander	Fire	NaN	309	39	52	43	60	50	65
    
    對 HP, Attack, Defense, Sp. Atk, Sp. Def, Speed 進行加總,驗證是否為 Total 值。
    
    對於 # 重複的妖怪只保留第一條記錄,解決以下問題:
    
    求第一屬性的種類數量和前三多數量對應的種類
    
    求第一屬性和第二屬性的組合種類
    
    求尚未出現過的屬性組合
    
    按照下述要求,構造 Series :
    
    取出物攻,超過120的替換為 high ,不足50的替換為 low ,否則設為 mid
    
    取出第一屬性,分別用 replace 和 apply 替換所有字母為大寫
    
    求每個妖怪六項能力的離差,即所有能力中偏離中位數最大的值,新增到 df 並從大到小排序
    
    #1、對 HP, Attack, Defense, Sp. Atk, Sp. Def, Speed 進行加總,驗證是否為 Total 值。
    s = [(df['HP']+df['Attack']+df['Defense']+df['Sp. Atk']+df['Sp. Def']+df['Speed']).values == df['Total'].values][0]
    set(s)
    out:{True}

    第一問的思路相對簡單,就是把這幾列的數相加然後判斷和total的值是否相等,返回bool陣列,再去重,發現得到Ture ,那麼證明這些列的和就是total。

2、對於#重複的妖怪只保留第一條記錄,解決以下問題:

a、求第一屬性的種類數量和前三多數量對應的種類

b、求第一屬性和第二屬性的組合種類

c、求尚未出現過的屬性組合

#對於 # 重複的妖怪只保留第一條記錄,解決以下問題:
df.drop_duplicates(['#'],keep='first')
	#	Name	Type 1	Type 2	Total	HP	Attack	Defense	Sp. Atk	Sp. Def	Speed
0	1	Bulbasaur	Grass	Poison	318	45	49	49	65	65	45
1	2	Ivysaur	Grass	Poison	405	60	62	63	80	80	60
2	3	Venusaur	Grass	Poison	525	80	82	83	100	100	80
4	4	Charmander	Fire	NaN	309	39	52	43	60	50	65
5	5	Charmeleon	Fire	NaN	405	58	64	58	80	65	80
...	...	...	...	...	...	...	...	...	...	...	...
793	717	Yveltal	Dark	Flying	680	126	131	95	131	98	99
794	718	Zygarde50% Forme	Dragon	Ground	600	108	100	121	81	95	95
795	719	Diancie	Rock	Fairy	600	50	100	150	100	150	50
797	720	HoopaHoopa Confined	Psychic	Ghost	600	80	110	60	150	130	70
799	721	Volcanion	Fire	Water	600	80	110	120	130	90	70

#求第一屬性的種類數量和前三多數量對應的種類
df['Type 1'].nunique()
out:18

df['Type 1'].value_counts()[:3]
Water     112
Normal     98
Grass      70
Name: Type 1, dtype: int64

#求第一屬性和第二屬性的組合種類
len(df.dropna().drop_duplicates(['Type 1','Type 2']))
out:136

#求尚未出現過的屬性組合
dta = df.dropna().drop_duplicates(['Type 1','Type 2'])
tpye = df[ df['Type 2'].isna()]['Type 1'].unique()#type1 種類
#已有組合
type1_2 = list(zip(dta['Type 1'],dta['Type 2']))
type1_2.append( list(zip(dta['Type 2'],dta['Type 1'])))
import itertools
com = list(itertools.permutations(tpye, 2))
list(set(list(com[0]))^set(list(type1_2[1])))
emt = []
for i in com:
    if i not in type1_2:
        emt.append(i)

ned_ls = []
for i in emt:
    for j in emt:
        if list(set(list(i))^set(list(j))) != []:
            ned_ls.append(i)           
list(set(ned_ls))

本題重點在第三個問,求出為出現的組合,我這裡將單屬性的抽出來去重,使用itertools.permutations來進行兩兩組合,然後將Type1和type2進行zip,注意,這裡為了防止原資料中的組合順序問題(a,b)(b,a)的情況,我這裡將type1和type2交換順序額進行了組合,然後for迴圈遍歷原組合和新組合列表,找出新的組合,找出新組合後再對新的組合進行順序去重保證不會出現(a,b)(b,a)同時出現的情況。

3、按照下述要求,構造Series

  1. 取出物攻,超過120的替換為high,不足50的替換為low,否則設為mid

  2. 取出第一屬性,分別用replaceapply替換所有字母為大寫

  3. 求每個妖怪六項能力的離差,即所有能力中偏離中位數最大的值,新增到df並從大到小排序

dat_att = df['Attack']
def re(x):
    if x > 120:
        x = 'high'
    elif x<50:
        x = ' low'
    else:
        x = 'mid'
    return x

dat_att.apply(re)

0       low
1       mid
2       mid
3       mid
4       mid
       ... 
795     mid
796    high
797     mid
798    high
799     mid
Name: Attack, Length: 800, dtype: object

#取出第一屬性,分別用 replace 和 apply 替換所有字母為大寫
typ1 = df['Type 1'].apply(lambda x : x.upper())
df['Type 1'].replace(df['Type 1'].values,(df['Type 1'].str.upper().values))
0        GRASS
1        GRASS
2        GRASS
3        GRASS
4         FIRE
        ...   
795       ROCK
796       ROCK
797    PSYCHIC
798    PSYCHIC
799       FIRE
Name: Type 1, Length: 800, dtype: object

#求每個妖怪六項能力的離差,即所有能力中偏離中位數最大的值,新增到 df 並從大到小排序
ds = df.loc[:,'HP':]
ds.apply(lambda x:(x-x.median()).abs().max()).sort_values(ascending = False)

感覺這個文就是靈活應用函式對映,要對pandas的各種函式功能熟悉。

Ex2:指數加權視窗

  1. 作為擴張視窗的ewm視窗

在擴張視窗中,使用者可以使用各類函式進行歷史的累計指標統計,但這些內建的統計函式往往把視窗中的所有元素賦予了同樣的權重。事實上,可以給出不同的權重來賦給視窗中的元素,指數加權視窗就是這樣一種特殊的擴張視窗。

其中,最重要的引數是alpha,它決定了預設情況下的視窗權重為wi=(1−α)i,i∈{0,1,...,t}wi=(1−α)i,i∈{0,1,...,t},其中i=ti=t表示當前元素,i=0i=0表示序列的第一個元素。

從權重公式可以看出,離開當前值越遠則權重越小,若記原序列為x,更新後的當前元素為ytyt,此時通過加權公式歸一化後可知:

對於Series而言,可以用ewm物件如下計算指數平滑後的序列:

def ewm_alpha(x, alpha=0.2):
    win = (1-alpha)**np.arange(x.shape[0])[::-1]
    res = (win*x).sum()/win.sum()
    return res
s.expanding().apply(ewm_func).head()

這題思路其實就是將加權歸一化的公式表達出來。

2.作為滑動視窗的ewm視窗

從第1問中可以看到,ewm作為一種擴張視窗的特例,只能從序列的第一個元素開始加權。現在希望給定一個限制視窗n,只對包含自身的最近的n個元素作為視窗進行滑動加權平滑。請根據滑窗函式,給出新的wiwi與ytyt的更新公式,並通過rolling視窗實現這一功能。

s.rolling(window=2).apply(ewm_alpha).head() 

這題兩問總結一下其實就是一個問題,就是定義加權公式歸一華後的公式,這裡要熟練使用numpy。