删除DataFrame中的重复项保持行具有最少的空值

时间:2017-05-03 20:45:19

标签: python pandas

使用此DataFrame:

d = {'A' : pd.Series(['AA', 'AA', 'AA', 'BB','CC'], 
           index=['a', 'b', 'c', 'd','e']),
     'B' : pd.Series([1., 2., 3.], index=['b', 'd','e']),
     'C' : pd.Series([4., 5., 6.], index=['b', 'd', '']),
     'D' : pd.Series([1., 2., 3.,4.], index=['a', 'c', 'd','e'])}

In[1]: pd.DataFrame(d)

Out[1]: 
     A    B    C    D
 a  AA  NaN  NaN  1.0
 b  AA  1.0  4.0  NaN
 c  AA  NaN  NaN  2.0
 d  BB  2.0  5.0  3.0
 e  CC  3.0  6.0  4.0

我想删除df['A']上的重复项,并在未被删除的列中保留最少空值的行on

In[2]: pd.DataFrame(d).drop_duplicates(on='A', **magical_answer=True**)

Out[1]: 
     A    B    C    D
 b  AA  1.0  4.0  NaN
 d  BB  2.0  5.0  3.0
 e  CC  3.0  6.0  4.0

我可以看到,如果有多行具有最少的空值,则会出现此示例中未列举的可能问题,在这种情况下,拥有keep : {‘first’, ‘last’} arg会很有用。

4 个答案:

答案 0 :(得分:5)

另一种方法是计算每行中的项目数,对DataFrame进行排序并保留最后一项,使其具有最高计数。

(df.assign(counts=df.count(axis=1))
   .sort_values(['A', 'counts'])
   .drop_duplicates('A', keep='last')
   .drop('counts', axis=1))
Out: 
    A    B    C    D
b  AA  1.0  4.0  NaN
d  BB  2.0  5.0  3.0
e  CC  3.0  6.0  4.0

答案 1 :(得分:4)

如果您没有重复索引,则可以执行以下操作:

df.loc[df.notnull().sum(1).groupby(df.A).idxmax()]

#    A    B   C   D
#b  AA  1.0 4.0 NaN
#d  BB  2.0 5.0 3.0
#e  CC  3.0 6.0 4.0

答案 2 :(得分:2)

让我们尝试利用count不计算NaN的优势:

df_out = df.groupby('A', as_index=False).apply(lambda x: x[(x.count(axis=1)==x.count(axis=1).max())])

OR

df_out = df.groupby('A', as_index=False).apply(lambda x: x.loc[x.count(axis=1).idxmax()])
print(df_out)

输出:

      A    B    C    D
0 b  AA  1.0  4.0  NaN
1 d  BB  2.0  5.0  3.0
2 e  CC  3.0  6.0  4.0

答案 3 :(得分:1)

使用 na_position='last' 对所有列的值进行排序。然后使用 drop_duplicate 函数并使用 keep='first'

d_out = d.sort_values(by=list(d.columns),na_position='last').drop_duplicates('A',keep='first')

输出:

    A   B   C   D
b   AA  1.0 4.0 NaN
d   BB  2.0 5.0 3.0
e   CC  3.0 NaN 4.0