使用pandas

时间:2017-06-11 00:05:37

标签: python pandas dataframe

我的数据看起来像:

Identifier  Category1 Category2 Category3 Category4 Category5
1000           foo      bat       678         a.x       ld
1000           foo      bat       78          l.o       op
1000           coo      cat       678         p.o       kt
1001           coo      sat       89          a.x       hd
1001           foo      bat       78          l.o       op
1002           foo      bat       678         a.x       ld
1002           foo      bat       78          l.o       op
1002           coo      cat       678         p.o       kt

我要做的是比较1000到1001和1002,依此类推。我希望代码给出的输出是:1000与1002相同。因此,我想要使用的方法是:

  1. 首先将所有标识符项分组为单独的数据帧(可能是?)。例如,df1将是属于标识符1000的所有行,df2将是属于标识符1002的所有行。(**请注意,我希望代码自己执行此操作,因为有数百万行,而不是我编写代码手动比较标识符**)。我尝试过使用pandas的groupby功能,它可以很好地进行分组,但后来我不知道如何比较这些组。
  2. 比较每个组/子数据帧。
  3. 我想到的一种方法是将特定标识符的每一行读入数组/向量,并使用比较度量(曼哈顿距离,余弦相似性等)比较数组/向量。

    感谢任何帮助,我是Python的新手。提前谢谢!

2 个答案:

答案 0 :(得分:3)

您可以执行以下操作:

import pandas as pd

input_file = pd.read_csv("input.csv")
columns = ['Category1','Category2','Category3','Category4','Category5']

duplicate_entries = {}

for group in input_file.groupby('Identifier'):
    # transforming to tuples so that it can be used as keys on a dict
    lines = [tuple(y) for y in group[1].loc[:,columns].values.tolist()]    
    key = tuple(lines) 

    if key not in duplicate_entries:
        duplicate_entries[key] = []

    duplicate_entries[key].append(group[0])

然后duplicate_entries值将包含重复标识符列表

duplicate_entries.values()
> [[1000, 1002], [1001]]

编辑:

要仅获取具有重复项的条目,您可以使用以下内容:

all_dup = [dup for dup in duplicate_entries if len(dup) > 1]

解释索引(抱歉,我之前没有解释过):迭代df.groupby结果给出了一个元组,其中第一个条目是组的关键(in在这种情况下,它将是一个“标识符”,第二个是一系列分组的数据帧。因此,要获取包含重复条目的行,我们会使用[1]和'标识符'该组可在[0]找到。因为在duplicate_entries数组中我们喜欢该条目的标识符,所以使用group[0]会让我们知道。

答案 1 :(得分:1)

我们可以使用groupby分组,然后按除"Identifier"之外的所有列对所有组进行排序(因此我们可以检测等于行的顺序相等)并比较组:

假设columns = ["Identifier", "Category1", "Category2", "Category3", "Category4", "Category5"]

我们可以这样做:

groups = []
pure_groups = []
for name, group in df.groupby("Identifier"):
    pure_groups += [group]
    g_idfless = group[group.columns.difference(["Identifier"])]
    groups += [g_idfless.sort_values(columns[1:]).reset_index().drop("index", axis=1)]

并比较它们:

for i in range(len(groups)):
    for j in range(i + 1, len(groups)):
        id1 = str(pure_groups[i]["Identifier"].iloc[0])
        id2 = str(pure_groups[j]["Identifier"].iloc[0])
        print(id1 + " and " + id2 + " equal?: " + str(groups[i].equals(groups[j])))

#-->1000 and 1001 equal?: False
#-->1000 and 1002 equal?: True
#-->1001 and 1002 equal?: False

编辑:添加了代码以打印与

匹配的组的标识符