我有一个数据框:
data = {'fruit': ['pear','pear','banana', 'pear', 'pear','apple', 'melon', 'cherry','cherry'],
'country': ['russia','usa', 'russia', 'russia','ghana','russia', 'russia', 'albania','andorra'],
'id': ['011','011','011', '011', '011','011', '6', '6','6'],
'month': ['march','march', 'november', 'march', 'january','january', 'march', 'january','july']
}
df = pd.DataFrame(data, columns = ['fruit','country', 'id', 'month'])
我想通过 'id'
删除每个组中的连续重复项。
我有
cols = ["fruit"]
de_dup = a[cols].loc[(df[cols].shift() != df[cols]).any(axis=1)]
但不使用 groupby。
我如何使用 groupby('id')
运行它,有人能看到问题吗?
输出数据帧:
答案 0 :(得分:1)
另一种没有 groupby 的方法:
df.assign(dupkey=(df[cols].shift() != df[cols]).cumsum()).drop_duplicates('dupkey')
输出:
fruit country id month dupkey
0 pear russia 011 march 1
2 banana russia 011 november 2
3 pear russia 011 march 3
5 apple russia 011 january 4
6 melon russia 6 march 5
7 cherry albania 6 january 6
和 groupby
df.groupby((df[cols].shift() != df[cols]).cumsum().squeeze(), as_index=False).first()
输出:
fruit country id month
0 pear russia 011 march
1 banana russia 011 november
2 pear russia 011 march
3 apple russia 011 january
4 melon russia 6 march
5 cherry albania 6 january
答案 1 :(得分:1)
为了避免使用 groupby,您可以简单地同时比较“id”和“fruit”,如下所示:
subset = df[["id", "fruit"]]
# marks all contiguous repeats of "id" and "fruit" as True
contiguous_duplicates = (subset == subset.shift()).all(axis=1)
new_df = df.loc[~contiguous_duplicates, :]
print(new_df)
fruit country id month
0 pear russia 011 march
2 banana russia 011 november
3 pear russia 011 march
5 apple russia 011 january
6 melon russia 6 march
7 cherry albania 6 january
说明:
subset = df[["id", "fruit"]]
我们在这里所做的只是抓取我们想要比较的所有相关列>>> print(subset)
id fruit
0 011 pear
1 011 pear
2 011 banana
3 011 pear
4 011 pear
5 011 apple
6 6 melon
7 6 cherry
8 6 cherry
(subset == subset.shift())
所做的就是将所有行向下移动一个并将其与原始子集进行比较。当我们比较它们时,它会返回一个布尔数据框(与 subset
大小相同),其 True/False 值对应于该值是否与来自同一行/列的前一个值相同。 id fruit
0 False False
1 True True
2 True False
3 True False
4 True True
5 True False
6 False False
7 True False
8 True True
在上面的框架中,您可以看到我们将移位子集的每个值与原始子集进行了比较。如果值为 True,则表示它与前一行中的值相同。请注意,由于重复的“id”值,“id”列有很多 True
值。
.all(axis=1)
现在我们有一个布尔数据框,我们想检查整行是否为 True
,如果它们是,这意味着整行与数据框中的前一行相同。这些是我们想要删除的行,因为它们是“连续重复”。0 False
1 True
2 False
3 False
4 True
5 False
6 False
7 False
8 True
dtype: bool
现在这个 Series
表示前一个布尔数据帧在整行中为 True 的位置。由于这些是我们想要删除(而不是保留)的行,我们需要翻转这个布尔值 Series
,这可以使用波浪号 ~
运算符完成:
df.loc[~contiguous_duplicates, :]
反转上述布尔值 Series
并使用它从原始数据框中选择行。