2016-11-22 80 views
1

我有一個數據集,看起來有點像這樣:Python的大熊貓 - 如果某些值爲空行合併

ID Name   Address  Zip Cost 
1 Bob the Builder 123 Main St 12345 
1 Bob the Builder      $99,999.99 
2 Bob the Builder 123 Sub St 54321 $74,483.01 
3 Nigerian Prince Area 51  33333 $999,999.99 
3 Pinhead Larry Las Vegas 31333 $11.00 
4 Fox Mulder  Area 51    $0.99 

,其中丟失的數據是正常的,除非很明顯,他們可以合併。我的意思是,而不是上面的數據集,我想合併ID和名稱都相同的行,其他功能可以填充對方的空白。例如,上面的數據集將成爲:

ID Name   Address  Zip Cost 
1 Bob the Builder 123 Main St 12345 $99,999.99 
2 Bob the Builder 123 Sub St 54321 $74,483.01 
3 Nigerian Prince Area 51  33333 $999,999.99 
3 Pinhead Larry Las Vegas 31333 $11.00 
4 Fox Mulder  Area 51    $0.99 

我已經想過使用df.groupby(["ID", "Name"])然後連接字符串,因爲缺失值是空字符串,但沒有得到運氣吧。

數據已被刮掉網站,所以他們不得不經過大量清理才能到達此處。我想不出一個解決這個問題的優雅方法!

回答

0

我將描述一個算法:

  1. 拋開所有字段填充的所有行。我們不需要碰這些。
  2. 創建一個布爾型DataFrame,如空字段爲False且填充字段爲True時的輸入。這是df.notnull()
  3. 對於每名df.Name.unique()
    1. df[df.Name == name]作爲工作集。
    2. 對布爾行的每對(或元組)進行求和,生成一個布爾向量與輸入列相同的寬度,除了那些總是填充的布爾向量。在這個例子中,這意味着[True, True, False][False, False, True],所以總和是[1, 1, 1]
    3. 如果總和等於1,則該行(或元組)行可以合併。

但也有一噸的可能的邊緣案件在這裏,比如,如果你有三排A,B,C,你可以合併是A + B或A + C做什麼。如果您可以在實施合併算法之前縮小數據中存在的約束條件,這將有所幫助。

+0

謝謝你的最後一排了很多!當我在數據框上做一個groupby()時,我注意到了這種模式,但並不知道如何處理它。我應該澄清一些限制因素 - 邊緣案例已經被處理了,所以它只有兩行重複的設置。 – kug3lblitz

1

這隻適用於我們可能合併的行彼此相鄰。

設置

df = pd.DataFrame(dict(
     ID=[1, 1, 2, 3, 3, 4], 
     Name=['Bob the Builder'] * 3 + ['Nigerian Prince', 'Pinhead Larry', 'Fox Mulder'], 
     Address=['123 Main St', '', '123 Sub St', 'Area 51', 'Las Vegas', 'Area 51'], 
     Zip=['12345', '', '54321', '33333', '31333', ''], 
     Cost=['', '$99,999.99', '$74,483.01', '$999.999.99', '$11.00', '$0.99'] 
    ))[['ID', 'Name', 'Address', 'Zip', 'Cost']] 

填補缺失
replace('', np.nan)再往前填補然後回填土

df_ = df.replace('', np.nan).ffill().bfill() 

孔卡牛逼
採取填補了df_如果重複行
採取非填充df如果不重複

pd.concat([ 
     df_[df_.duplicated()], 
     df.loc[df_.drop_duplicates(keep=False).index] 
    ]) 

enter image description here