DataWhale組隊學習pandas task02
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
:
-
取出物攻,超過120的替換為
high
,不足50的替換為low
,否則設為mid
-
取出第一屬性,分別用
replace
和apply
替換所有字母為大寫 -
求每個妖怪六項能力的離差,即所有能力中偏離中位數最大的值,新增到
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:指數加權視窗
-
作為擴張視窗的
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。