Pandas - 从另一列中删除具有最高值的重复行
Pandas - remove duplicate rows except the one with highest value from another column
我有一个大型数据框(超过 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,但我认为存在一个错误,他们会丢弃您的旧索引,我认为他们不应该...第 n 个是但是有效。
另一种方法是先切出不等于 liq max 的那些:
(df[df["liq"] == g["liq"].transform("max")] # keep only max liq rows
.groupby(["unique_id", "period_id"])
.nth(0)
我有一个大型数据框(超过 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,但我认为存在一个错误,他们会丢弃您的旧索引,我认为他们不应该...第 n 个是但是有效。
另一种方法是先切出不等于 liq max 的那些:
(df[df["liq"] == g["liq"].transform("max")] # keep only max liq rows
.groupby(["unique_id", "period_id"])
.nth(0)