如何计算pandas数据帧中的重复行?

jss*_*367 43 python pandas

我试图计算我的数据帧中每种类型的行的重复项.例如,假设我在pandas中有一个数据帧,如下所示:

df = pd.DataFrame({'one': pd.Series([1., 1, 1]),
                   'two': pd.Series([1., 2., 1])})
Run Code Online (Sandbox Code Playgroud)

我得到一个看起来像这样的df:

    one two
0   1   1
1   1   2
2   1   1
Run Code Online (Sandbox Code Playgroud)

我想第一步是找到所有不同的唯一行,我这样做:

df.drop_duplicates()
Run Code Online (Sandbox Code Playgroud)

这给了我以下df:

    one two
0   1   1
1   1   2
Run Code Online (Sandbox Code Playgroud)

现在我想从上面的df([1 1]和[1 2])中获取每一行,并计算每个在初始df中的次数.我的结果看起来像这样:

Row     Count
[1 1]     2
[1 2]     1
Run Code Online (Sandbox Code Playgroud)

我该怎么办呢?

编辑:

这是一个更大的例子,使其更清晰:

df = pd.DataFrame({'one': pd.Series([True, True, True, False]),
                   'two': pd.Series([True, False, False, True]),
                   'three': pd.Series([True, False, False, False])})
Run Code Online (Sandbox Code Playgroud)

给我:

    one three   two
0   True    True    True
1   True    False   False
2   True    False   False
3   False   False   True
Run Code Online (Sandbox Code Playgroud)

我想要一个告诉我的结果:

       Row           Count
[True True True]       1
[True False False]     2
[False False True]     1
Run Code Online (Sandbox Code Playgroud)

EdC*_*ica 41

您可以groupby在所有列上调用size索引指示重复值:

In [28]:
df.groupby(df.columns.tolist(),as_index=False).size()

Out[28]:
one    three  two  
False  False  True     1
True   False  False    2
       True   True     1
dtype: int64
Run Code Online (Sandbox Code Playgroud)


小智 27

df.groupby(df.columns.tolist()).size().reset_index().\
    rename(columns={0:'records'})

   one  two  records
0    1    1        2
1    1    2        1
Run Code Online (Sandbox Code Playgroud)

  • 这应该是公认的答案。 (4认同)

Ser*_*sev 11

我用:

used_features =[
    "one",
    "two",
    "three"
]

df['is_duplicated'] = df.duplicated(used_features)
df['is_duplicated'].sum()
Run Code Online (Sandbox Code Playgroud)

它给出了重复行的计数,然后你可以通过一个新列来分析它们。我在这里没有看到这样的解决方案。


Ara*_*ash 8

如果您想计算特定列上的重复项:

len(df['one'])-len(df['one'].drop_duplicates())
Run Code Online (Sandbox Code Playgroud)

如果要在整个数据帧上计算重复项:

len(df)-len(df.drop_duplicates())
Run Code Online (Sandbox Code Playgroud)

或者简单地,您可以使用DataFrame.duplicated(subset = None,keep ='first')

df.duplicated(subset='one', keep='first').sum()
Run Code Online (Sandbox Code Playgroud)

哪里

子集:列标签或标签序列(默认情况下使用所有列)

keep:{'first','last',False},默认为'first'

  • first:将第一次出现的重复项标记为True。
  • last:将最后一次出现的重复项标记为True。
  • False:将所有重复项标记为True。

  • 正如您提到的 EdChum 在所有列上的解决方案和在特定列上的解决方案。我想补充一点 ``df.groupby(df["my_column"].tolist(),as_index=False).size()``` 可用于在列上获取 groupby (2认同)

小智 8

如果您只需要查找唯一行和重复行(整行重复)的计数,则可以使用以下方法:

df.duplicated().value_counts()

输出:假 11398 真 154 数据类型:int64


oli*_*man 7

现有的答案都没有提供一个简单的解决方案来返回“只是重复的行数,应该被删除”。这是一种一刀切的解决方案,它可以:

# generate a table of those culprit rows which are duplicated:
dups = df.groupby(df.columns.tolist()).size().reset_index().rename(columns={0:'count'})

# sum the final col of that table, and subtract the number of culprits:
dups['count'].sum() - dups.shape[0]
Run Code Online (Sandbox Code Playgroud)


Sea*_*ean 6

如果您发现某些计数丢失或出现错误:ValueError: Length mismatch: Expected axis has nnnn elements, new values have mmmm elements,请阅读此处:

1. 计算包含条目的重复NaN行:

被接受的解决方案很棒,相信对许多成员都有帮助。在最近的一项任务中,我发现它可以进一步微调以支持带有条目的数据帧的完整NaN计数。Pandas 支持缺失条目或空值作为NaN值。NaN让我们看看当我们的数据帧包含条目时此用例的输出是什么:

  Col1  Col2 Col3 Col4
0  ABC   123  XYZ  NaN       # group #1 of 3
1  ABC   123  XYZ  NaN       # group #1 of 3
2  ABC   678  PQR  def           # group #2 of 1
3  MNO   890  EFG  abc               # group #3 of 4 
4  MNO   890  EFG  abc               # group #3 of 4 
5  CDE   234  567  xyz                   # group #4 of 2 
6  ABC   123  XYZ  NaN       # group #1 of 3
7  CDE   234  567  xyz                   # group #4 of 2 
8  MNO   890  EFG  abc               # group #3 of 4 
9  MNO   890  EFG  abc               # group #3 of 4 
Run Code Online (Sandbox Code Playgroud)

应用代码:

df.groupby(df.columns.tolist(),as_index=False).size()
Run Code Online (Sandbox Code Playgroud)

给出:

  Col1  Col2 Col3 Col4  size
0  ABC   678  PQR  def     1
1  CDE   234  567  xyz     2
2  MNO   890  EFG  abc     4
Run Code Online (Sandbox Code Playgroud)

哦,为什么有 3 个重复行的第 1 组的计数丢失了?!

对于某些 Pandas 版本,您可能会收到错误消息:ValueError: Length mismatch: Expected axis has nnnn elements, new values have mmmm elements

解决方案:

dropna=使用函数的参数.groupby(),如下所示:

df.groupby(df.columns.tolist(), as_index=False, dropna=False).size()
Run Code Online (Sandbox Code Playgroud)

给出:

  Col1  Col2 Col3 Col4  size
0  ABC   123  XYZ  NaN     3          # <===  count of rows with `NaN`
1  ABC   678  PQR  def     1
2  CDE   234  567  xyz     2
3  MNO   890  EFG  abc     4
Run Code Online (Sandbox Code Playgroud)

NaN可以使用 成功输出重复行的计数dropna=FalsePandas 1.1.0 版本开始支持该参数


2.替代解决方案

另一种计算条目重复NaN行的方法如下:

df.value_counts(dropna=False).reset_index(name='count')
Run Code Online (Sandbox Code Playgroud)

给出:

  Col1  Col2 Col3 Col4  count
0  MNO   890  EFG  abc      4
1  ABC   123  XYZ  NaN      3
2  CDE   234  567  xyz      2
3  ABC   678  PQR  def      1
Run Code Online (Sandbox Code Playgroud)

在这里,我们使用.value_counts()带有参数 的函数dropna=False但是,自Pandas 版本 1.3.0以来,最近才支持此参数。如果您的版本早于此版本,.groupby()如果您想获取包含条目的行的完整计数,则 需要使用该解决方案NaN

您将看到输出的顺序与之前的结果不同。计数按降序排列。如果你想得到未排序的结果,你可以指定sort=False

df.value_counts(dropna=False, sort=False).reset_index(name='count')
Run Code Online (Sandbox Code Playgroud)

它给出与解决方案相同的结果df.groupby(df.columns.tolist(), as_index=False, dropna=False).size()

  Col1  Col2 Col3 Col4  count
0  ABC   123  XYZ  NaN      3
1  ABC   678  PQR  def      1
2  CDE   234  567  xyz      2
3  MNO   890  EFG  abc      4
Run Code Online (Sandbox Code Playgroud)

请注意,该.value_counts()解决方案支持带条目和不带NaN条目的数据帧,并且可以用作通用解决方案。

其实底层实现代码中.value_counts()调用GroupBy.size获取counts:点击链接查看底层代码:counts = self.groupby(subset, dropna=dropna).grouper.size()

因此,对于这个用例,公认的解决方案中的解决.value_counts()方案.groupby()实际上在做同样的事情。我们应该能够使用该.value_counts()函数同样很好地获得所需的重复行数。

使用.value_counts()函数来获取重复行的计数还有一个额外的好处,即其语法更简单。您可以简单地使用df.value_counts()df.value_counts(dropna=False)取决于您的数据帧NaN是否包含。.reset_index()如果您希望结果作为数据框而不是系列,则链接。