python - Pandas - 删除重复行,但另一列中具有最高值的行除外

标签 python pandas duplicates max apply

我有一个大型数据框(超过 100 列和数十万行),其中有许多行包含重复数据。我试图删除重复的行,将具有最大值的行保留在不同的列中。

从本质上讲,我是根据时间段将数据分类到各个箱子中,因此在各个时间段内,人们会发现很多重复项,因为大多数实体都存在于所有时间段内。但是,不允许同一实体在给定时间段内多次出现。

我尝试了 python pandas: Remove duplicates by columns A, keeping the row with the highest value in column B 中的方法,在数据的一个子集上,计划与原始数据框 df 重新组合。

示例数据子集:

              unique_id   period_id   liq
index                                   
19            CAN00CE0     199001  0.017610
1903          **USA07WG0** 199001  1.726374
12404         **USA07WG0** 199001  0.090525
13330         USA08DE0     199001  1.397143
14090         USA04U80     199001  2.000716
12404         USA07WG0     199002  0.090525
13330         USA08DE0     199002  1.397143
14090         USA04U80     199002  2.000716

在上面的示例中,我想保留第一个实例(因为 liq 较高,为 1.72)并丢弃第二个实例(liq 较低,为 0.09)。请注意,在给定的 period_id 中可以有两个以上的重复项。

我试过了,但是对我来说它非常很慢(我在 5 分钟后停止了它):

def h(x):
    x = x.dropna() #idmax fails on nas, and happy to throw out where liq is na.
    return x.ix[x.liq.idmax()]

df.groupby([‘holt_unique_id’, ‘period_id’], group_keys = False).apply(lambda x: h(x))

我最终做了下面的,它更冗长和丑陋,除了一个重复的以外,其他的都扔掉了,但这也很慢!考虑到类似复杂度的其他操作的速度,我想我会在这里寻求更好的解决方案。

所以我的要求实际上是修复上面的代码以便它更快,下面给出了指导,如果按照下面的思路,也许我也可以根据索引丢弃重复项,而不是我采用的 reset_index/set_index 方法:

def do_remove_duplicates(df):
    sub_df = df[['period_id', 'unique_id']] 
    grp = sub_df.groupby(['period_id', 'unique_id'], as_index = False)
    cln = grp.apply(lambda x: x.drop_duplicates(cols = 'unique_id'))   #apply drop_duplicates.  This line is the slow bit!
    cln = cln.reset_index()   #remove the index stuff that has been added
    del(cln['level_0'])   #remove the index stuff that has been added
    cln.set_index('level_1', inplace = True)   #set the index back to the original (same as df).
    df_cln = cln.join(df, how = 'left', rsuffix = '_right')   # join the cleaned dataframe with the original, discarding the duplicate rows using a left join.
    return df_cln

最佳答案

这个怎么样:

  • 用最大数据更新所有列。
  • 选择一行(比如第一行)。

这应该更快,因为它是矢量化的。

In [11]: g = df.groupby(["unique_id", "period_id"], as_index=False)

In [12]: g.transform("max")
Out[12]:
            liq
index
19     0.017610
1903   1.726374
12404  1.726374
13330  1.397143
14090  2.000716
12404  0.090525
13330  1.397143
14090  2.000716

In [13]: df.update(g.transform("max"))

In [14]: g.nth(0)
Out[14]:
          unique_id  period_id       liq
index
19         CAN00CE0     199001  0.017610
1903   **USA07WG0**     199001  1.726374
13330      USA08DE0     199001  1.397143
14090      USA04U80     199001  2.000716
12404      USA07WG0     199002  0.090525
13330      USA08DE0     199002  1.397143
14090      USA04U80     199002  2.000716

注意:我想在此处首先或最后使用 groupby,但我认为存在一个错误,他们会丢弃您的旧索引,我认为他们不应该...然而第 nth 是可行的。


另一种方法是先切出不等于 liq max 的那些:

(df[df["liq"] == g["liq"].transform("max")]  #  keep only max liq rows
 .groupby(["unique_id", "period_id"])
 .nth(0)

关于python - Pandas - 删除重复行,但另一列中具有最高值的行除外,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34420864/

相关文章:

python - 根据字典用数值替换字符串

python - 如何在 Pandas 中读取奇怪的 csv 文件?

python - 迭代数据帧时所做的更改不会保存

python - 删除 pandas 中的列

c++ - 检测多个枚举项何时映射到相同的值

search - 在Elasticsearch中查找重复项

返回多个列表的 Python 列表理解

python - 如何检查我是否可以发送电子邮件?

python - Pandas iloc 不返回数据切片

python - Spark 中的分组线性回归