检测CSV中具有不同列数的记录
我需要每天将 CSV 文件摄取到pandas dataframe. CSV 有几千行,但每天我都会收到一些列比预期多的记录。让我给你举个例子。采取以下措施CSV:
Name, Address, Phone
John Doe, 777 Street, 3145678777
Jane Doe, 888 Street, 3145678888
Chris Doe, Adam Smith, 999 Street, 3145679999
Ellen Page, 222 Street, 3145679222
这是我的导入行:
df = pd.read_csv(myfile.csv, header = 0, names = ['Name, 'Address', 'Phone'])
正如预期的那样,第 3 ( Chris Doe, Adam Smith, 999 Street, 3145679999)行打破了这个过程,因为它有一个额外的列。我的源数据来自的应用程序似乎允许用户在Name字段中输入逗号,有时,当多个用户共享同一个家庭时,他们会这样做。我无法更改应用程序。
我的目标是简单地检测这些行并将它们移动到单独的文本文件或数据框,任何有意义的东西。我可以单独处理这些记录,那很好。
我似乎有一些帖子旨在处理具有不同记录数的 CSV。我认为这会使我的过程复杂化,就我而言,这是不值得的。
对于如何以最直接和最简单的方式实现这一目标的任何帮助,我将不胜感激。
谢谢!
回答
$ awk -F, 'NF>3' file
Chris Doe, Adam Smith, 999 Street, 3145679999
$ awk -F, '{print > (NF>3 ? "bad" : "good")}' file
$ head bad good
==> bad <==
Chris Doe, Adam Smith, 999 Street, 3145679999
==> good <==
Name, Address, Phone
John Doe, 777 Street, 3145678777
Jane Doe, 888 Street, 3145678888
Ellen Page, 222 Street, 3145679222
或者您可以修复您的 CSV 以引用“名称”字段,如果它包含逗号:
$ awk -F, 'NF>3{rest=$(NF-1) FS $NF; sub(/(,[^,]*){2}$/,""); $0=""" $0 ""," rest} 1' file
Name, Address, Phone
John Doe, 777 Street, 3145678777
Jane Doe, 888 Street, 3145678888
"Chris Doe, Adam Smith", 999 Street, 3145679999
Ellen Page, 222 Street, 3145679222
或总是:
$ awk -F, '{rest=$(NF-1) FS $NF; sub(/(,[^,]*){2}$/,""); $0=""" $0 ""," rest} 1' file
"Name", Address, Phone
"John Doe", 777 Street, 3145678777
"Jane Doe", 888 Street, 3145678888
"Chris Doe, Adam Smith", 999 Street, 3145679999
"Ellen Page", 222 Street, 3145679222
如果您使用的是很旧,不符合POSIX标准的awk不支持正则表达式的时间间隔,那么你可以使用sub(/,[^,]*,[^,]*$/,"")的替代sub(/(,[^,]*){2}$/,"")。
请参阅使用 awk 有效解析 CSV 的最可靠方法是什么?有关使用 awk 操作 CSV 的更多信息。