使用 numpy.genfromtxt 读取包含逗号的字符串的 csv 文件
Posted
技术标签:
【中文标题】使用 numpy.genfromtxt 读取包含逗号的字符串的 csv 文件【英文标题】:Using numpy.genfromtxt to read a csv file with strings containing commas 【发布时间】:2013-07-29 18:55:46 【问题描述】:我正在尝试使用 numpy.genfromtxt
读取 csv 文件,但其中一些字段是包含逗号的字符串。字符串用引号引起来,但 numpy 没有将引号识别为定义单个字符串。例如,使用 't.csv' 中的数据:
2012, "Louisville KY", 3.5
2011, "Lexington, KY", 4.0
代码
np.genfromtxt('t.csv', delimiter=',')
产生错误:
ValueError:检测到一些错误! 第 2 行(得到 4 列而不是 3 列)
我要找的数据结构是:
array([['2012', 'Louisville KY', '3.5'],
['2011', 'Lexington, KY', '4.0']],
dtype='|S13')
查看文档,我没有看到任何处理此问题的选项。有没有办法用 numpy 来做,还是我只需要用 csv
模块读入数据,然后将其转换为 numpy 数组?
【问题讨论】:
你能发布更多完整的 csv,我想我知道如何解决你的问题 ;) 你应该改变你的 csv 替换分隔符从,
到 ;
例如...
@SaulloCastro:我不能这样做,因为我的真实数据更加混乱,并且包含带有;
和/或您能想到的任何其他字符的字符串 - 这只是一个玩具示例。我正在寻找的是一个更通用的解决方案。
@EiyrioüvonKauyf:正如我所提到的,这只是一个说明问题的玩具示例,但我认为它具有所有基本功能。您到底在寻找什么?
【参考方案1】:
您可以为此使用pandas(在科学 python 中用于处理数据帧(异构数据)的成为默认库)。 read_csv
可以处理这个问题。来自文档:
引号:字符串
The character to used to denote the start and end of a quoted item. Quoted items can include the delimiter and it will be ignored.
默认值为"
。一个例子:
In [1]: import pandas as pd
In [2]: from StringIO import StringIO
In [3]: s="""year, city, value
...: 2012, "Louisville KY", 3.5
...: 2011, "Lexington, KY", 4.0"""
In [4]: pd.read_csv(StringIO(s), quotechar='"', skipinitialspace=True)
Out[4]:
year city value
0 2012 Louisville KY 3.5
1 2011 Lexington, KY 4.0
这里的诀窍是您还必须使用skipinitialspace=True
来处理逗号分隔符后的空格。
除了强大的 csv 阅读器之外,我还强烈建议您将 pandas 与您拥有的异构数据一起使用(您提供的 numpy 示例输出都是字符串,尽管您可以使用结构化数组)。
【讨论】:
太棒了,就像一个魅力。我听说过一些关于pandas
的信息,但之前从未尝试过——这似乎是一个很好的机会。顺便说一句,我试图让我的初始示例保持简单,但实际上我打算使用 np.recfromcsv
来获取结构化的 numpy 数组。【参考方案2】:
附加逗号的问题,np.genfromtxt
没有解决这个问题。
一个简单的解决方案是从 python 的 csv 模块中读取带有 csv.reader()
的文件到一个列表中,然后根据需要将其转储到一个 numpy 数组中。
如果你真的想使用np.genfromtxt
,请注意它可以使用迭代器而不是文件,例如np.genfromtxt(my_iterator, ...)
。因此,您可以将 csv.reader
包装在迭代器中并将其提供给 np.genfromtxt
。
会是这样的:
import csv
import numpy as np
np.genfromtxt(("\t".join(i) for i in csv.reader(open('myfile.csv'))), delimiter="\t")
这实质上只是用制表符即时替换了适当的逗号。
【讨论】:
嗯,我明白你在这里得到了什么,但我玩了一点,但仍然无法让它正常工作。无论如何,我想今天我会选择pandas
路线。无论如何,谢谢。【参考方案3】:
如果您使用的是 numpy,您可能希望使用 numpy.ndarray。这会给你一个 numpy.ndarray:
import pandas
data = pandas.read_csv('file.csv').as_matrix()
Pandas 会正确处理“肯塔基州列克星敦”案
【讨论】:
请注意,如果这样做,第一行可能会丢失。第一行被视为数据框的列标签。as_matrix()
将很快被弃用。请改用.values
。【参考方案4】:
结合标准csv
module 和Numpy 的recfromcsv
的强大功能,制作一个更好的函数。例如csv
模块对方言、引号、转义字符等有很好的控制和自定义,您可以将其添加到下面的示例中。
下面的示例 genfromcsv_mod
函数读取一个复杂的 CSV 文件,类似于 Microsoft Excel 看到的文件,其中可能包含引号字段中的逗号。在内部,该函数有一个生成器函数,它用制表符分隔符重写每一行。
import csv
import numpy as np
def recfromcsv_mod(fname, **kwargs):
def rewrite_csv_as_tab(fname):
with open(fname, newline='') as fp:
dialect = csv.Sniffer().sniff(fp.read(1024))
fp.seek(0)
for row in csv.reader(fp, dialect):
yield "\t".join(row)
return np.recfromcsv(
rewrite_csv_as_tab(fname), delimiter="\t", encoding=None, **kwargs)
# Use it to read a CSV file into a record array
x = recfromcsv_mod("t.csv", case_sensitive=True)
【讨论】:
我相信它应该是open(fname, 'r')
,否则它会在传递字节而不是字符串时引发错误
@Guillaume 谢谢,这是针对 Python 2 的,但已针对 Python 3 进行了更新。【参考方案5】:
你可以试试这个代码。我们正在从 np.genfromtext() 读取 .csv 文件 方法 代码:
myfile = np.genfromtxt('MyData.csv', delimiter = ',')
myfile = myfile.astype('int64')
print(myfile)
输出:
[[ 1 1 1 1 1 1 1 1 1 1 1]
[ 3 3 3 3 3 3 3 3 3 3 3]
[ 3 3 3 3 3 3 3 3 3 3 3]
[ 4 4 4 4 4 4 4 4 4 4 4]
[ 5 5 5 5 5 5 5 5 5 5 5]
[ 6 6 6 6 6 6 6 6 6 6 6]
[ 7 7 7 7 7 7 7 7 7 7 7]
[ 8 8 8 8 8 8 8 8 8 8 8]
[ 9 9 9 9 9 9 9 9 9 9 9]
[10 10 10 10 10 10 10 10 10 10 10]
[11 11 11 11 11 11 11 11 11 11 11]
[12 12 12 12 12 12 12 12 12 12 12]
[13 13 13 13 13 13 13 13 13 13 13]
[14 14 14 14 14 14 14 14 14 14 14]
[15 15 15 15 15 15 15 15 15 15 15]
[16 17 18 19 20 21 22 23 24 25 26]]
输入文件“MyData.csv”
希望对您有所帮助??
【讨论】:
以上是关于使用 numpy.genfromtxt 读取包含逗号的字符串的 csv 文件的主要内容,如果未能解决你的问题,请参考以下文章
numpy genfromtxt IndexError 使用评论时