我有一个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 -
当我们通过几次不同的检索获取数据时,这似乎是一个非常常见的问题。但我无法找到一种清理数据的有效方法。
答案 0 :(得分:1)
如果索引已经是列,那么您可以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 -
答案 1 :(得分:1)
您可以使用groupby/transform
创建一个布尔掩码True
,其中组计数大于1,并且该行中的任何值等于'-'
。然后,您可以使用df.loc[~mask]
选择未屏蔽的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 -