使用 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导入数据

numpy genfromtxt IndexError 使用评论时

numpy.genfromtxt 导入元组而不是数组

使用 numpy.genfromtxt 在 Python 3 中加载 UTF-8 文件

Numpy函数学习--genfromtxt函数

NumPy genfromtxt:正确使用filling_missing