【问题标题】:Pandas and python: deduplication of dataset by several fields [closed]Pandas 和 python:通过多个字段对数据集进行重复数据删除 [关闭]
【发布时间】:2021-08-07 03:36:23
【问题描述】:

我有一个公司数据集。每个公司都有纳税人号码、地址、电话等一些字段。这是我从 Roméo Després 那里得到的 Pandas 代码:

import pandas as pd

df = pd.DataFrame({
    "tax_id": ["A", "B", "C", "D", "E", "A", "B", "C", "F", "E"],
    "phone": [0, 1, 2, 3, 4, 5, 0, 0, 6, 3],
    "address": ["x", "y", "z", "x", "y", "x", "t", "z", "u", "v"],
})
print(df)

  tax_id  phone address
0      A      0       x
1      B      1       y
2      C      2       z
3      D      3       x
4      E      4       y
5      A      5       x
6      B      0       t
7      C      0       z
8      F      6       u
9      E      3       v

我需要通过这些字段对数据集进行重复数据删除,这意味着非唯一公司只能通过这些字段之一链接。 IE。某些公司在我的列表中绝对是唯一的,前提是它没有任何关键字段的任何匹配项。如果公司与其他实体共享纳税人编号,并且该实体与第三个实体共享地址,则所有三个公司都是同一个。独特公司的预期产出应该是:

  tax_id  phone address
0      A      0       x
1      B      1       y
2      C      2       z
8      F      6       u

每个副本的预期输出以及唯一的公司索引应如下所示:

  tax_id  phone address  representative_index
0      A      0       x                     0
1      B      1       y                     1
2      C      2       z                     2
3      D      3       x                     0
4      E      4       y                     1
5      A      5       x                     0
6      B      0       t                     0
7      C      0       z                     0
8      F      6       u                     8
9      E      3       v                     3

在这种情况下,如何使用 python/pandas 过滤掉重复项?

我想到的唯一算法是以下直接方法:

  1. 我按第一个键对数据集进行分组,将其他键收集为集合 结果数据集
  2. 然后我用第二个键迭代地走过集合,然后 添加到我的分组数据集中以获得第一个键新的第二个键的一些值 值,一遍又一遍地迭代它们。
  3. 最后没有什么要补充的了,我对第三个键重复这个。

就性能和编码的简单性而言,这看起来不太有希望。

还有其他方法可以通过几个键之一删除重复项吗?

【问题讨论】:

标签: python pandas algorithm duplicates dataset


【解决方案1】:

您可以使用图形分析库networkx 解决此问题。

import itertools

import networkx as nx
import pandas as pd


df = pd.DataFrame({
    "tax_id": ["A", "B", "C", "D", "E", "A", "B", "C", "F", "E"],
    "phone": [0, 1, 2, 3, 4, 5, 0, 0, 6, 3],
    "address": ["x", "y", "z", "x", "y", "x", "t", "z", "u", "v"],
})

def iter_edges(df):
    """Yield all relationships between rows."""
    for name, series in df.iteritems():
        for nodes in df.groupby(name).indices.values():
            yield from itertools.combinations(nodes, 2)

def iter_representatives(graph):
    """Yield all elements and their representative."""
    for component in nx.connected_components(graph):
        representative = min(component)
        for element in component:
            yield element, representative


graph = nx.Graph()
graph.add_nodes_from(df.index)
graph.add_edges_from(iter_edges(df))

df["representative_index"] = pd.Series(dict(iter_representatives(graph)))

最后df的样子:

  tax_id  phone address  representative_index
0      A      0       x                     0
1      B      1       y                     0
2      C      2       z                     0
3      D      3       x                     0
4      E      4       y                     0
5      A      5       x                     0
6      B      0       t                     0
7      C      0       z                     0
8      F      6       u                     8
9      E      3       v                     0

请注意,您可以通过 df.drop_duplicates("representative_index") 获取唯一行:

  tax_id  phone address  representative_index
0      A      0       x                     0
8      F      6       u                     8

【讨论】:

  • 罗密欧,很好的解决方案!
  • 罗密欧,你认为有没有办法为每个重复设置唯一的“代表”,意思是:第 5 行是第 0 行(按税号),第 3 行又是第 0 行(按地址)?
  • 当然,刚刚用这个编辑了答案。您可能应该编辑您的问题并添加两个预期输出(在我的示例中为unique_companiesdf["representative_index"]
  • 非常感谢!我已经编辑了这个问题,我希望他们会重新打开它。
  • 罗密欧,最后一部分好像有瑕疵。见第 9 行。它有代表索引=3,但第 3 行本身不是唯一的。第9行应该有representative_index = 0。当某行通过另一行与“根”连接时,第9行是一个触摸案例。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-22
  • 1970-01-01
  • 1970-01-01
  • 2020-11-11
相关资源
最近更新 更多