2017-09-19 93 views
2

問題通過丟棄缺失的元素

冷凝熊貓數據幀我有一個數據幀,看起來像這樣:

Key Var ID_1 Var_1 ID_2 Var_2 ID_3 Var_3 
1 True 1.0 True NaN NaN 5.0 True 
2 True NaN NaN  4.0 False 7.0 True 
3 False 2.0 False 5.0 True NaN NaN 

每一行有數據的恰好2非空集(ID/VAR),其餘三分之一保證爲空。我想要做的是通過刪除缺少的元素來「濃縮」數據框。

所需的輸出

Key Var  First_ID First_Var Second_ID Second_Var 
1 True 1   True  5   True 
2 True 4   False  7   True 
3 False 2   False  5   True 

的順序不是重要的,只要該ID /無功對被保持。


目前的解決方案

下面是我有一個有效的解決方案:

import pandas as pd 
import numpy as np 

data = pd.DataFrame({'Key': [1, 2, 3], 'Var': [True, True, False], 'ID_1':[1, np.NaN, 2], 
        'Var_1': [True, np.NaN, False], 'ID_2': [np.NaN, 4, 5], 'Var_2': [np.NaN, False, True], 
        'ID_3': [5, 7, np.NaN], 'Var_3': [True, True, np.NaN]}) 

sorted_columns = ['Key', 'Var', 'ID_1', 'Var_1', 'ID_2', 'Var_2', 'ID_3', 'Var_3'] 
data = data[sorted_columns] 

output = np.empty(shape=[data.shape[0], 6], dtype=str) 

for i, *row in data.itertuples(): 
    output[i] = [element for element in row if np.isfinite(element)] 

print(output) 


[['1' 'T' '1' 'T' '5' 'T'] 
['2' 'T' '4' 'F' '7' 'T'] 
['3' 'F' '2' 'F' '5' 'T']] 

這是可以接受的,但不理想。我可以生活在沒有列名的地方,但我最大的問題是不得不將數據內的數據轉換爲字符串,以避免我的布爾轉換爲數字。

還有其他解決方案在保存數據方面做得更好嗎?如果結果是熊貓數據框,則爲獎勵點。

回答

3

有一個簡單的解決方案即推的NaN向右拖放上軸1.即

所述的NaN
ndf = data.apply(lambda x : sorted(x,key=pd.isnull),1).dropna(1) 

輸出:

 
    Key Var ID_1 Var_1 ID_2 Var_2 
0 1 True 1 True 5 True 
1 2 True 4 False 7 True 
2 3 False 2 False 5 True 

希望它能幫助。

從Divakar here一個numpy的解決方案爲10X速度即

def mask_app(a): 
    out = np.full(a.shape,np.nan,dtype=a.dtype) 
    mask = ~np.isnan(a.astype(float)) 
    out[np.sort(mask,1)[:,::-1]] = a[mask] 
    return out 

ndf = pd.DataFrame(mask_app(data.values),columns=data.columns).dropna(1) 
 
    Key Var ID_1 Var_1 ID_2 Var_2 
0 1 True 1 True 5 True 
1 2 True 4 False 7 True 
2 3 False 2 False 5 True 
+1

那是相當聰明+1 – 2Obe

+0

這工作 - 這是不以最快的速度解決numpy的,但它確實保存數據的原始格式。 – ZachTurn

+0

如果你在問題中添加numpy標籤,那麼numpy專家可能會提供更快的答案,這本來就不錯。 – Dark