gpt4 book ai didi

c# - 如何按 2 列比较两个 csv 文件?

转载 作者:太空宇宙 更新时间:2023-11-03 21:08:57 24 4
gpt4 key购买 nike

我有 2 个 csv 文件

1.csv

spain;russia;japan
italy;russia;france

2.csv

spain;russia;japan
india;iran;pakistan

我读取两个文件并将数据添加到列表

var lst1= File.ReadAllLines("1.csv").ToList();
var lst2= File.ReadAllLines("2.csv").ToList();

然后我从两个列表中找到所有唯一的字符串并将其添加到结果列表中

var rezList = lst1.Except(lst2).Union(lst2.Except(lst1)).ToList();

rezlist 包含这些数据

[0] = "italy;russia;france"
[1] = "india;iran;pakistan"

现在我想通过所有行中的secondthird 列来比较、生成except 和union。

1.csv

西类牙;俄罗斯;日本

意大利;俄罗斯;法国

2.csv

西类牙;俄罗斯;日本

印度;伊朗;巴基斯坦

我想我需要用符号 ';' 拆分所有行并进行所有 3 操作(exceptdistinctunion)但无法理解如何操作。

rezlist必须包含

india;iran;pakistan

我添加了类

 class StringLengthEqualityComparer : IEqualityComparer<string>
{

public bool Equals(string x, string y)
{
...
}

public int GetHashCode(string obj)
{
...
}
}



StringLengthEqualityComparer stringLengthComparer = new StringLengthEqualityComparer();
var rezList = lst1.Except(lst2,stringLengthComparer ).Union(lst2.Except(lst1,stringLengthComparer),stringLengthComparer).ToList();

最佳答案

您的问题不是很清楚:例如,india;iran;pakistan 是否是期望的结果,主要是因为 russia 位于 element[1]?不也是因为元素[2]pakistan没有匹配到francejapan吗?尽管还不清楚,但我认为无论哪种情况都会产生预期的结果。

然后是这样的:从两个列表中找到所有唯一的字符串,它极大地改变了性质。所以,我认为期望的结果是因为“iran”出现在列 [1] 中,没有出现在任何文件的列 [1] 中的其他地方,即使它出现了,由于 col 中的“pakistan”,该行仍然是唯一的[2].

另请注意,2 的数据样本为相当多的错误留下了空间。

尝试一步完成会让人非常困惑。由于消除在 1.CSV 中发现的重复项非常容易,因此请先执行此操作:

// parse "1.CSV"
List<string[]> lst1 = File.ReadAllLines(@"C:\Temp\1.csv").
Select(line => line.Split(';')).
ToList();

// parse "2.CSV"
List<string[]> lst2 = File.ReadAllLines(@"C:\Temp\2.csv").
Select(line => line.Split(';')).
ToList();

// extracting once speeds things up in the next step
// and leaves open the possibility of iterating in a method
List<List<string>> tgts = new List<List<string>>();
tgts.Add(lst1.Select(z => z[1]).Distinct().ToList());
tgts.Add(lst1.Select(z => z[2]).Distinct().ToList());

var tmpLst = lst2.Where(x => !tgts[0].Contains(x[1]) ||
!tgts[1].Contains(x[2])).
ToList();

这导致项目不在 1.CSV 中(在 Col[1] 和 Col[2] 中没有匹配的文本)。如果这真的是您所需要的,那么您就完成了。

在 2.CSV 中获取唯一行比较棘手,因为您必须实际计算每个 Col[1] 项出现的次数以查看它是否唯一;然后重复 Col[2]。这使用了 GroupBy:

var unique = tmpLst.
GroupBy(g => g[1], (key, values) =>
new GroupItem(key,
values.ToArray()[0],
values.Count())
).Where(q => q.Count == 1).
GroupBy(g => g.Data[2], (key, values) => new
{
Item = string.Join(";", values.ToArray()[0]),
Count = values.Count()
}
).Where(q => q.Count == 1).Select(s => s.Item).
ToList();

GroupItem 类很简单:

class GroupItem
{
public string Item { set; get; } // debug aide
public string[] Data { set; get; }
public int Count { set; get; }

public GroupItem(string n, string[] d, int c)
{
Item = n;
Data = d;
Count = c;
}
public override string ToString()
{
return string.Join(";", Data);
}
}

它以 tmpList 开始,获取在 [1] 处具有唯一元素的行。它使用一个类进行存储,因为此时我们需要数组数据以供进一步审查。

第二个 GroupBy 作用于这些结果,这次查看 col[2]。最后,它选择连接的字符串数据。

结果

在 File1 (1.3 MB) 中使用 50,000 个随机项,在 File2 (390 kb) 中使用 15,000 个。没有自然产生的唯一项,所以我在 2.CSV 中手动制作了 8 个唯一项,并将其中 2 个复制到 1.CSV 中。如果 2.CSV 中的 8 个唯一行使预期结果为 6 个唯一行,则 1.CSV 中的副本应消除 2:

enter image description here

NepalXItalyX 是两个文件中的重复项,它们正确地相互消除了。

在每一步中,它都在扫描和处理越来越少的数据,这似乎使其对于 65,000 行/130,000 个数据元素的速度相当快。

关于c# - 如何按 2 列比较两个 csv 文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39046533/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com