天天看點

Task 5 合并 學習筆記複習提綱練習一【練習二】reference

源自pandas組隊學習計劃

複習提綱

一、append和assign

  1. append方法
  • 利用序列添加行(須指定name)
  • 用DataFrame添加表

(添加不會作用在原資料框中,需指定接收變量 )

  1. assign方法
  • 用于添加列,列名在形式參數時指定
  • 多列同時添加

二、combine和update

  1. 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的缺失值,簡單實用,這意味着可以不加形式參數。

  1. 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)
           
Task 5 合并 學習筆記複習提綱練習一【練習二】reference
  • key參數

四、merge和join

  1. 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 顯示合并後該行索引的來源
  1. 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])
           
Task 5 合并 學習筆記複習提綱練習一【練習二】reference
# (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()
           
Task 5 合并 學習筆記複習提綱練習一【練習二】reference
在(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())
           
Task 5 合并 學習筆記複習提綱練習一【練習二】reference
# (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()
           
Task 5 合并 學習筆記複習提綱練習一【練習二】reference
# (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拆分。
           
Task 5 合并 學習筆記複習提綱練習一【練習二】reference

我對比了一下groupby前後的專業課表,确實是僅僅缺值資料被動了,其他沒有出現錯誤。

這說明在分組、轉換值之後,資料框依然保持着原來的順序,不因被分組了而颠倒為分組順序。

reference

這位對問題做了回答!!