Python 将格式错误的csv文件转换为numpy数组

Python 将格式错误的csv文件转换为numpy数组,python,csv,numpy,Python,Csv,Numpy,我有一个csv文件,有7行,其中5行有7列,最后两行有2列。这些文件也是字符串、浮点和NaN的混合体。 e、 g: 我可以用MATLAB阅读这个文件并进行处理。我能用numpy做同样的事吗? 我试图在这个论坛上寻找解决方案,但似乎没有任何效果。需要将字符串和NAN转换为浮点。我不确定是否有使用NumPy的解决方案,loadtxt和genfromtxt在列数发生变化时分别引发错误和警告,因此您可能必须编写自己的方法 编辑:以下内容略为编辑,以反映DSM的意见 您可以使用内置的csv模块: impo

我有一个csv文件,有7行,其中5行有7列,最后两行有2列。这些文件也是字符串、浮点和NaN的混合体。 e、 g:

我可以用MATLAB阅读这个文件并进行处理。我能用numpy做同样的事吗?
我试图在这个论坛上寻找解决方案,但似乎没有任何效果。需要将字符串和NAN转换为浮点。

我不确定是否有使用NumPy的解决方案,
loadtxt
genfromtxt
在列数发生变化时分别引发错误和警告,因此您可能必须编写自己的方法

编辑:以下内容略为编辑,以反映DSM的意见

您可以使用内置的
csv
模块:

import csv

arr = []

with open('test.txt', 'r') as fh:
    reader = csv.reader(fh)
    for row in reader:
        if row:
            arr.extend(row)
csv方法的优点是它剥离了换行符,如果您只是使用
fileobj=open(…)
读取文件中的行,则情况并非如此

在这一点上,你应该

>>> arr
['883825.00', '373395.00', '0.00', '20,080.84', '2012500.00', '#EANF#', '121449.
39', '0.00', '0.00', '0.00', '38,849.10', '0.00', '#EANF#', '0.00', '0.00', '0.0
0', '0.00', '83,167.42', '1640625.00', '#EANF#', '0.00', '#EANF#', '#EANF#', '#E
ANF#', '#EANF#', '#EANF#', '#EANF#', '#EANF#', '-1,202,600.00', '-0.00', '#EANF#
', '2267168', '0.00', '#EANF#', '-173,710.66', '-125.60', '#EANF#', '17,459.68',
 '#EANF#.']
然后,您必须转换为浮点数,并将
EANF
值替换为,例如,
numpy.NaN
。我们还必须注意一些值中的逗号。逗号很容易处理

float(str(float_string).replace(',', ''))
对于
#EANF#
值,我们只需检查一个项目是否以此开头(不等于此,因为列表中的最后一个项目后面有一个
)。将这两个转换组合成一个函数
convert
,并用列表进行包装:

import numpy

def convert(v):
    try:
        return float(v)
    except ValueError:
        if v.startswith('#EANF#'):
            return numpy.NaN
        else:
            return float(str(v).replace(',', ''))

arr = numpy.asarray([convert(a) for a in arr])
函数
convert
可以泛化为第二个可选参数,该参数定义哪些值应映射到
numpy.NaN

最终的结果是

>>> arr
[883825.0, 373395.0, 0.0, 20080.84, 2012500.0, nan, 121449.39, 0.0, 0.0, 0.0, 38
849.1, 0.0, nan, 0.0, 0.0, 0.0, 0.0, 83167.42, 1640625.0, nan, 0.0, nan, nan, na
n, nan, nan, nan, nan, -1202600.0, -0.0, nan, 2267168.0, 0.0, nan, -173710.66, -
125.6, nan, 17459.68, nan]

注意:此答案假设您对结果为一维列表感到满意。如果你想要一个不同的结果形状,你应该在问题中这样说。

我不确定是否有一个使用NumPy的解决方案,
loadtxt
genfromtxt
分别在列数改变时发出错误和警告,因此你可能必须编写自己的方法

编辑:以下内容略为编辑,以反映DSM的意见

您可以使用内置的
csv
模块:

import csv

arr = []

with open('test.txt', 'r') as fh:
    reader = csv.reader(fh)
    for row in reader:
        if row:
            arr.extend(row)
csv方法的优点是它剥离了换行符,如果您只是使用
fileobj=open(…)
读取文件中的行,则情况并非如此

在这一点上,你应该

>>> arr
['883825.00', '373395.00', '0.00', '20,080.84', '2012500.00', '#EANF#', '121449.
39', '0.00', '0.00', '0.00', '38,849.10', '0.00', '#EANF#', '0.00', '0.00', '0.0
0', '0.00', '83,167.42', '1640625.00', '#EANF#', '0.00', '#EANF#', '#EANF#', '#E
ANF#', '#EANF#', '#EANF#', '#EANF#', '#EANF#', '-1,202,600.00', '-0.00', '#EANF#
', '2267168', '0.00', '#EANF#', '-173,710.66', '-125.60', '#EANF#', '17,459.68',
 '#EANF#.']
然后,您必须转换为浮点数,并将
EANF
值替换为,例如,
numpy.NaN
。我们还必须注意一些值中的逗号。逗号很容易处理

float(str(float_string).replace(',', ''))
对于
#EANF#
值,我们只需检查一个项目是否以此开头(不等于此,因为列表中的最后一个项目后面有一个
)。将这两个转换组合成一个函数
convert
,并用列表进行包装:

import numpy

def convert(v):
    try:
        return float(v)
    except ValueError:
        if v.startswith('#EANF#'):
            return numpy.NaN
        else:
            return float(str(v).replace(',', ''))

arr = numpy.asarray([convert(a) for a in arr])
函数
convert
可以泛化为第二个可选参数,该参数定义哪些值应映射到
numpy.NaN

最终的结果是

>>> arr
[883825.0, 373395.0, 0.0, 20080.84, 2012500.0, nan, 121449.39, 0.0, 0.0, 0.0, 38
849.1, 0.0, nan, 0.0, 0.0, 0.0, 0.0, 83167.42, 1640625.0, nan, 0.0, nan, nan, na
n, nan, nan, nan, nan, -1202600.0, -0.0, nan, 2267168.0, 0.0, nan, -173710.66, -
125.6, nan, 17459.68, nan]

注意:此答案假设您对结果为一维列表感到满意。如果您希望结果的形状不同,您应该在问题中这样说。

最后两行的预期结果是什么?预期结果分别为-125.6和17459.68。最后两行的预期结果是什么?预期结果分别为-125.6和17459.68。”(它将此视为单一价值-有人知道解决此问题的方法吗?)我认为它是一个单一的值,只是用逗号作为千位分隔符。这就是为什么引用这些值。我没有想到这一点-因此csv模块无疑是前进的方向。我将更新我的答案以反映这一点。谢谢!我放弃用Python做这件事,因为它是用Excel本身实现的。我将在以后的某个时候尝试它我对Python有了更多的了解。感谢并对延迟回答表示抱歉。“(它将此视为一个单一值-有人知道解决此问题的方法吗?)我认为它是一个单一的值,只是用逗号作为千位分隔符。这就是为什么引用这些值。我没有想到这一点-因此csv模块无疑是前进的方向。我将更新我的答案以反映这一点。谢谢!我放弃用Python做这件事,因为它是用Excel本身实现的。我将在以后的某个时候尝试它我已经学习了更多的Python。感谢并对延迟回答表示抱歉。