删除数据表中的重复项
我有以下实现来查找DataTable中的重复项。这是非常低效的,并且需要大约20K行。我只需要找到重复项,第二列的值:删除数据表中的重复项
private List<string> checkForDuplicates(DataTable results)
{
List<string> duplicateLists = new List<string>();
for (int i = 0; i < results.Rows.Count; i++)
{
string cellvalue = results.Rows[i][1].ToString();
for (int j = 0; j < results.Rows.Count; j++)
{
if (i != j)
{
if (cellvalue.Equals(results.Rows[j][1]))
{
//Duplicate found
duplicateLists.Add(results.Rows[i][1].ToString() + "_" + i+2 + "_" + j+2);
}
}
}
}
return duplicateLists;
}
你得到的问题是,每一行都必须检查每隔一行,因此对于更多的行,检查的次数呈指数增长。处理它的最快方法是使它成为线性的 - 只做多行检查。
执行此操作的一种方法是按列2对数据表进行排序。这会将任何重复项放在相邻的行中,因此您只需要遍历表来检查一行是否与下一行不匹配。
另一种方式是从源头获取东西,并在读取它们之前确保行是不同的。
Aaargh,为什么我没有想到,今天脑死亡。谢谢。 – n4rzul 2011-03-10 14:58:23
但排序也意味着对比值彼此,不? – Matthias 2011-03-10 15:02:20
@bender。当发生这种情况时,发生这种情况:假设你有3行,那么检查的次数是3 * 3 = 9(粗略地说,其中的一些可能会被省略,但其大致为真)。当您添加另一行时,您有4 * 4 = 16个检查,然后是25,36等。因此对于20K行,您有4亿检查。当你排序时,你只需要检查下一行,因此对于3行你需要2次检查。对于4行,您需要3.对于20k行,您需要19,999个检查。这就是为什么你在性能上有了这样的改进。 – 2011-03-10 15:35:33
DataTable distinctTable = originalTable.DefaultView.ToTable(/*distinct*/ true);
你的目的,你可以做一个数据视图仅包含列()你”重新感兴趣。
难道不是所有的列都不能区分而不是仅仅是列吗? – 2011-03-10 14:54:47
就像我说过的,你可以创建一个DataView,其中只包含column2,或者显然你可以使用列表调用ToTable:DataTable uniqueTable = dvwDataView.ToTable(true,“name”,“next_column_name”,“another_column_name”); – 2011-03-10 14:57:04
它会,不是什么即时通讯寻找,乔恩你的第一个答案是完美的。 – n4rzul 2011-03-10 14:58:01
您可以做的一个优化是对已排序的数据集进行重复数据删除。定义一个DataView,对相关列的数据进行排序,然后检查当前行的值是否与前一行的值不同。
马克索索尔的答案可能是一个更好的主意,如果你不打扰物理删除行然而。
SQL会更有效地完成此操作,而不是将整个数据集拉两次。
如果您所指的列上有索引,则可以非常快速地完成。
只是做
SELECT id AS matchID, column1 FROM table1 WHERE column1 IN (SELECT column1 FROM table1 WHERE id IS NOT matchId)
或类似的东西
干杯, 尼科
源数据是csv – n4rzul 2011-03-15 05:59:39
使用字典和全值迭代一次,并计算每个值的发生=>词典关键是列值,字典值是计数。 然后返回计数超过一个的所有键。
这个工作得很好,但我去了Jon的回答是,因为他的解决方案让我感觉更自然。结果代码很容易理解,我正在处理大约20-60K行。 60K行觉得它永远不会完成旧的“比较所有值”方法,其中排序和检查相邻记录几乎是即时的,包括排序。 – n4rzul 2011-03-15 06:03:54
你有比较的专栏索引吗? – NikoRoberts 2011-03-10 14:53:37