如果列是NaN,并且存在列不是NaN的另一行,如何在Dataframe中删除行

时间:2017-11-21 04:35:52

标签: python pandas dataframe nan

我在python中有一个pandas数据帧,其中行由p1& p2,但p2有时是NaN

   p1 p2
0  a  1
1  a  2
2  a  3
3  b  NaN
4  c  4
5  d  NaN
6  d  5

上面的数据框是通过使用

从较大的数据框返回的,其中包含许多重复数据
df.drop_duplicates(subset=["p1","p2"], keep='last')

大部分都有效,唯一的问题是NaN5在技术上并不重复,因此不会被删除。

如何删除行(例如:"d", NaN),其中另一行具有相同的p1 p2值{{ 1}}例如。 not.null。这里重要的是保留"d", 5,因为没有"b", NaN

2 个答案:

答案 0 :(得分:1)

我们可以groupbyffill以及bfill,然后drop_duplicates

df.assign(p2=df.groupby('p1')['p2'].apply(lambda x : x.ffill().bfill())).\
      drop_duplicates(subset=["p1","p2"], keep='last')
Out[645]: 
  p1   p2
0  a  1.0
1  a  2.0
2  a  3.0
3  b  NaN
4  c  4.0
6  d  5.0

答案 1 :(得分:1)

这组副本应该基本上是包含NaN值的所有行和包含重复p1元素的行的交集,与两列中重复的行联合:

dupe_1 = df['p1'].duplicated(keep=False) & df['p2'].isnull()
dupe_2 = df.duplicated(subset=['p1','p2'])
total_dupes = dupe_1 | dupe_2
new_df = df[~total_dupes]

请注意,对于数据框,例如:

,这将失败
  p1  p2
0  a NaN
1  a NaN

因为这两个元素都将被删除。因此,我们必须首先运行df.drop_duplicates(subset=['p1','p2'], inplace=True, keep='last'),删除除了其中一行之外的所有行,使解决方案再次正常工作。