如何获取A,B重复列中,第一个不为空C的值?

df内容

A   B   C
1   1   ""
1   1   1

df.drop_duplicates(subset=['A','B'], keep='first', inplace=False)

A   B   C
1   1   ""

我想要的结果是

A   B   C
1   1   1

保留第一个不为“”的C列的值

阅读 2.6k
2 个回答

你可以增加一个条件筛选,把有空值的那一行去掉,再drop_duplicates

老铁, 以下代码仅供参考:

我举个例子吧

先建立df

>>> df = [[1,2,''], [1,3,4], [1,2,3], [1,3,3], [1,2,4],[1,4,5], [1,4,6]]
>>> df = pd.DataFrame(a, columns=['A','B','C'])
>>> df
   A  B  C
0  1  2   
1  1  3  4
2  1  2  3
3  1  3  3
4  1  2  4
5  1  4  5
6  1  4  6

可以使用df.groupby()方法分组, 而其返回的值是可迭代对象, 该可迭代对象的每一个值是一个元组, 而每一个元组又有两个元素, 第一个元素是你的分组依据, 第二个元素是被你分割出来的DataFrame, 看个例子吧:

>>> for i in df.groupby(by=['A','B'],sort=False):
        print(i)
        print() # 打印个回车分割

    
((1, 2),    A  B  C
0  1  2   
2  1  2  3
4  1  2  4)

((1, 3),    A  B  C
1  1  3  4
3  1  3  3)

((1, 4),    A  B  C
5  1  4  5
6  1  4  6)

所以现在的问题是如何从每个元组的第二个元素中找到你要的第一个不为空C的值

应该比较简单吧, 再写个例子:

>>> b = pd.DataFrame([[1,2,''],[1,2,3], [1,2,4]], columns=['A','B','C'])
>>> print(b[b.C != ''].iloc[0])
A    1
B    2
C    3
Name: 1, dtype: object

所以一句话就可以写完:

>>> a.groupby(by=['A','B'],sort=False).apply(lambda x:x[x.C != ''].iloc[0]).reset_index(drop=True)
   A  B  C
0  1  2  3
1  1  3  4
2  1  4  5

但是问题又来了, 一旦原DataFrame中有[1,9,'']这样一项, A,B, 只出现一次没有重复过, 那就会报错

所以推荐自己写一个函数(就是传入apply()的那个)
给出参考:

def xx(x):
    try:
        return x[x.C != ''].iloc[0]
    except:
        return None

但是碰见[1,9,'']这一项就成了:

       A    B    C
A B               
1 2  1.0  2.0  3.0
  9  NaN  NaN  NaN
  3  1.0  3.0  4.0
  4  1.0  4.0  5.0

所以你还得手动删除那一行

行吧, 老铁希望你写的更简单一点, 当然如果数据够理想, 一行就够了

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题