删除具有重复索引的行

drop rows that have duplicated indices

我有一个 DataFrame,其中每个观察值都由 index 标识。但是,对于某些指数,DF 包含多个观察值。其中之一拥有最新的数据。我想根据某些列的值删除过时的重复行。

例如,在下面的 DataFrame 中,如何删除带有 index = 122 的第一行和第三行?

index col1 col2
122   -    -
122   one  two
122   -    two
123   four one
124   five -

也就是我想得到一个这样的最终DF:

index col1 col2
122   one  two
123   four one
124   five -

当我们随着时间的推移通过几次不同的检索获取数据时,这似乎是一个非常普遍的问题。但是我想不出一种有效的方法来清理数据。

如果索引已经是一列那么你可以drop_duplicates并传递参数take-last=True:

In [14]:

df.drop_duplicates('index', take_last=True)
Out[14]:
   index  col1 col2
1    122     -  two
2    123  four  one

如果它实际上是您的索引,那么您最好先调用 reset_index 然后执行上述步骤,然后重新设置索引。

Index 有一个调用 drop_duplicates 的方法,但这只是从索引中删除了重复项,删除了重复项的返回索引不允许您使用重复项索引回 df已删除,因此我通过在 df 本身上调用 drop_duplicates 来推荐上述方法。

编辑

根据您的新信息,最简单的方法可能是用 NaN 值替换过时数据并删除这些值:

In [36]:

df.replace('-', np.NaN).dropna()
Out[36]:
       col1 col2
index           
122     one  two
123    four  one

另一个编辑

你可以做的是 groupby 索引并获取剩余列的 first 值,然后调用 reset_index:

In [56]:

df.groupby('index')['col1', 'col2'].first().reset_index()

Out[56]:
   index  col1 col2
0    122     -    -
1    123  four  one
2    124  five    -

您可以使用 groupby/transform 创建一个布尔掩码 True,其中组计数大于 1 并且行中的任何值等于 '-'。然后你可以使用 df.loc[~mask] 到 select df:

的未屏蔽行
import pandas as pd

df = pd.read_table('data', sep='\s+')
count = df.groupby(['index'])['col1'].transform('count') > 1
mask = (df['col1'] == '-') | (df['col2'] == '-')
mask = mask & count
result = df.loc[~mask]
print(result)

产量

   index  col1 col2
0    122   one  two
1    123  four  one
2    124  five    -