源自pandas組隊學習計劃
複習提綱
一、append和assign
- append方法
- 利用序列添加行(須指定name)
- 用DataFrame添加表
(添加不會作用在原資料框中,需指定接收變量 )
- assign方法
- 用于添加列,列名在形式參數時指定
- 多列同時添加
二、combine和update
- combine方法
- combine和update方法用途:表的填充,設定填充規則
- (a)填充對象
combine函數是按照兩個資料框對應的一列列進行資料操作的!!
了解:可以看出combine方法是按照表的順序輪流進行逐列循環的,而且自動索引對齊,缺失值為NaN
這裡給出的例子中輸出資料全為NaN,這是因為後面的func指定的是列印,正常應該執行np.minimum等運算,按列取值計算後 輸出
-
(b)一些例子
例1中:列、行對應的元素進行比較,這裡是對整列的mean做對比的。我嘗試了一下整列直接比較是報錯的,提示我需要加上x.any()或者x.all()之類的方法.
例2中:索引對齊特性,也就是在預設狀态下,後面的表沒有的行列會設定成NaN,可以了解成,兩個資料框中同等位置的元素不全,就沒法比較啦!
在幫助文檔中,提示使用
fill_value=-5
這樣的形參補足缺失資料
例3中:“使得df1原來符合條件的值不會被覆寫”,用
overwrite=False
實作,大白話就是:有個别缺失資料沒關系,df1有的資料,df2沒有,那運算結果算df1的
這裡有個想法:他們之間是咋對比的呢,如果df2中僅僅缺一個資料,不是缺兩個,那怎麼判别呢??
例4:新增比對df2的元素位置填充-1
-
(c)combine_first方法
作用:用df2填補df1的缺失值,簡單實用,這意味着可以不加形式參數。
- update方法
-
(a)了解3特點
第二個資料框中的nan元素不起作用。
沒有傳回值,直接在df對象上操作。
傳回的資料框索引隻會與被調用的框一緻(預設左連接配接,這裡不懂的話看個例子就好了。)
-
(b)例子
pandas.DataFrame.update
展現的原則基本是:按照索引來對齊更新,沒有的就不填充(部分填充),缺失值不會填充。
三、concat方法
concat方法可以在兩個次元上拼接,預設縱向拼接(axis=0),拼接方式預設外連接配接。
簡單:
>>> s1 = pd.Series(['a', 'b'])
>>> s2 = pd.Series(['c', 'd'])
>>> pd.concat([s1, s2])
0 a
1 b
0 c
1 d
dtype: object
外連接配接:取拼接方向的并集,join=‘outer’ ,
而join='inner’時取拼接方向(若使用預設的縱向拼接,則為列的交集)的交集。
- axis=1 時設定沿着列方向拼接
- 形式參數join='inner’表示設定為内連接配接,例如預設axis=0,列取交集,即資料相交的那一個
- 可以将Series添加到df中
s = pd.Series(['x1','x3'], name='x')
pd.concat([df1, s], axis=1)
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnL2UDN1MDMxMjMwMDNwAjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
- key參數
四、merge和join
- merge函數
作用:将兩個pandas對象橫向合并,在遇到重複的索引項時使用笛卡爾積,預設how='inner’連接配接,可選left、outer、right連接配接。
左連接配接:以第一個表索引為基準,右邊的表中的索引不在左邊則不加入,如果在左邊則以笛卡爾積的方式加入。
merge與join函數與concat的不同在于on參數,可指定某個對象為key來連接配接。
如
pd.merge(df1,df2,how='outer'
就是将兩個資料并集,沒有的資料為nan。這裡的how就是concat方法中的join
了解笛卡爾積:[2, 2]與[2, 2, 2]有6個組合
>> left = pd.DataFrame({'A': [1, 2], 'B': [2, 2]})
>> right = pd.DataFrame({'A': [4, 5, 6], 'B': [2, 2, 2]})
>> pd.merge(left, right, on='B', how='outer')
A_x B A_y
0 1 2 4
1 1 2 5
2 1 2 6
3 2 2 4
4 2 2 5
5 2 2 6
- validate=‘one_to_one’ validate檢驗的是到底哪一邊出現了重複索引,如果是“one_to_one”則兩側索引都是唯一,如果"one_to_many"則左側唯一???
- indicator=True 顯示合并後該行索引的來源
- join函數
作用:将多個pandas對象橫向拼接,遇到重複的索引項使用笛卡爾積。
預設左連接配接,也有inner、outer、right連結。
left.join(right, on='key')
預設也是指定索引連結。
練習一
# (a) 每個公司有多少員工滿足如下條件:既出現第一張表,又出現在第二張表。
r = data1.merge(data2, how='inner', on=['Company','Name'])
display(r)
print('滿足..條件的人數為:', r.shape[0])
# (b) 将所有不符合(a)中條件的行篩選出來,合并為一張新表,列名與原表一緻。
L = list(r['Name'])
data1_b = data1[ ~data1['Name'].isin(L)]
data2_b = data2[ ~data2['Name'].isin(L)]
result_b = pd.concat([data1_b, data2_b], axis=0)
display(result_b.info())
result_b.head()
在(a)題中,使用join報錯了: en(left_on) must equal the number of levels in the index of "right"
,借此能認識到merge與join方法的不同,最少join必需行數相同。
【練習二】
有2張課程的分數表(分數随機生成),但專業課(學科基礎課、專業必修課、專業選修課)與其他課程混在一起,請解決如下問題:
# (a) 将兩張表分别拆分為專業課與非專業課(結果為四張表)
t1_a1 = t1[ (t1['課程類别']=='專業必修課') | (t1['課程類别']=='學科基礎課') | (t1['課程類别']=='專業選修課')]
print('專業課:')
display(t1_a1.head())
print('非專業課::')
t1_a2 = t1[ ~((t1['課程類别']=='專業必修課') | (t1['課程類别']=='學科基礎課') | (t1['課程類别']=='專業選修課'))]
display(t1_a2)
# 此時看到另一種寫法:
t2_a1 = t2.query("課程類别 in ['專業必修課','學科基礎課','專業選修課']")
t2_a2 = t2.query("課程類别 not in ['專業必修課','學科基礎課','專業選修課']")
print("表2的 專業課:")
display(t2_a1.head())
print("表2的 非專業課:")
display(t2_a2.head())
# (b) 将兩張專業課的分數表和兩張非專業課的分數表分别合并。
result_b1 = pd.concat([t1_a1, t2_a1], axis=0)
result_b2 = pd.concat([t1_a2, t2_a2], axis=0) #非專業課程 合并
display(result_b2.head())
# (c) 不使用(a)中的步驟,請直接讀取兩張表合并後拆分。 # 這個思路,資料操作量大些
cc = pd.concat([t1, t2],axis=0)
cc_2 = cc.query("課程類别 in ['專業必修課','學科基礎課','專業選修課']") #專業課
cc_3 = cc.query("課程類别 not in ['專業必修課','學科基礎課','專業選修課']") #
cc_3.head()
# (d) 專業課程中有缺失值嗎,如果有的話請在完成(3)的同時,用組内(3種類型的專業課)均值填充缺失值後拆分。
display( cc_2[cc_2.isnull().values==True] )
cc_2['分數'] = cc_2.groupby('課程類别').transform(lambda x:x.fillna(x.mean()))['分數']
display(cc_2.isnull().all())
# 拆分:還是用上面的query拆分。
我對比了一下groupby前後的專業課表,确實是僅僅缺值資料被動了,其他沒有出現錯誤。
這說明在分組、轉換值之後,資料框依然保持着原來的順序,不因被分組了而颠倒為分組順序。
reference
這位對問題做了回答!!