检查 numpy 输入尺寸的标准方法是什么?
What is the standard way to check the dimensions of a numpy input?
我有一系列特定格式的文本文件。例如,file.txt
如下所示,形状为 50 列字母和 70 行文本:
AAAAAAAAAAAA
BBBBBBBBBBBB
CCCCCCCCCCCC
DDDDDDDDDDDD
我想将以下内容放入一个 numpy 数组中,然后进行操作。这个数组将有一定的维度。形状类似于 50 列字母,70 行文本,例如形状(70,50)。但是,某些文本文件是 "missing letters"。有问题的文件看起来像这样
AAAAAAAAAAAA
BB BBBBBBBBB
CCCCCCCCCCCC
DDDDDD DDDDD
我想检查是否存在任何 "spaces",并抛出错误。是否有处理 numpy 数组的标准方法?我是在将文本输入数组之前还是之后执行此操作?
我可以对多个文件执行此操作吗?也就是说,如果我输入 200 个文件,最终结果是一个形状为 (200,70,50)
的 numpy 数组。
对于大部分工作,您不需要 numpy
。下面的代码将输入文件读入列表,每个元素将是输入文件的一行(删除尾随换行符)。然后它创建一个相同长度的列表,每个元素都表示给定的字符串是否小于 space。如果其中任何一个是False
,那么你就有问题了,你可以随意处理这个案例。否则 space-less 条目被读入字符串类型 numpy.ndarray
.
import numpy as np
#read data into list "lines"
with open('input.inp') as f:
lines = [line.rstrip('\n') for line in f]
#check ones with spaces
nospaces = [not ' ' in line for line in lines]
#throw an error here if you will
if not all(nospaces):
print('Uh-oh!')
#or just ignore the ones contaning a space and put the rest into an ndarray
goodlines = np.array(lines)[np.array(nospaces)] #the only numpy-specific part
示例input.inp
:
asfasf asfasfsa
asffsafsafa
asfafsafs afa
faaffasaff
fasafasffas
afssfafs asafsas
输出:
In [1131]: run foo.py
Uh-oh!
In [1132]: lines
Out[1132]:
['asfasf asfasfsa',
'asffsafsafa',
'asfafsafs afa',
'faaffasaff',
'fasafasffas',
'afssfafs asafsas']
In [1133]: goodlines
Out[1133]:
array(['asffsafsafa', 'faaffasaff', 'fasafasffas'],
dtype='|S16')
注意最后输出的是"16-character string"类型,因为我们先把list变成了数组,然后把不需要的部分扔掉了。通过较小的工作,您可以根据自己的喜好定制此解决方案,并且您的示例似乎也表明您的输入行具有相同的长度(在这种情况下,结果数组将具有最佳 dtype
)。
让我们用文本行列表模拟您的文件:
In [401]: txt="""\
AAAAAAAAAAAA
BB BBBBBBBBB
CCCCCCCCCCCC
DDDDDD DDDDD
"""
In [402]: txt=txt.splitlines()
In [403]: txt
Out[403]: ['AAAAAAAAAAAA', 'BB BBBBBBBBB', 'CCCCCCCCCCCC', 'DDDDDD DDDDD']
如何将其加载到数组中?我们经常使用 loadtxt
,但那是针对数据列
In [404]: np.loadtxt(txt,dtype=str)
Out[404]:
array(['AAAAAAAAAAAA', 'BB', 'CCCCCCCCCCCC', 'DDDDDD'],
dtype='|S12')
没用。
让我们split
在这些方面
In [410]: [x.split() for x in txt]
Out[410]: [['AAAAAAAAAAAA'], ['BB', 'BBBBBBBBB'], ['CCCCCCCCCCCC'], ['DDDDDD', 'DDDDD']]
包含 'white space' 的行变成包含超过 1 个术语的列表
In [411]: [len(x.split())>1 for x in txt]
Out[411]: [False, True, False, True]
所以有 2 行有错误。
我可以通过 list()
传递字符串,将 txt
变成每列一个字母的数组。这给出了 np.array
列表的列表,所有列表的长度都相同。行尾的 blank/whitespace 可能会导致问题。
In [414]: A=np.array([list(x) for x in txt])
In [415]: A
Out[415]:
array([['A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A'],
['B', 'B', ' ', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B'],
['C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C'],
['D', 'D', 'D', 'D', 'D', 'D', ' ', 'D', 'D', 'D', 'D', 'D']],
dtype='|S1')
我可以测试此数组的 ' '
个字符,例如:
In [418]: np.any(A==' ',axis=1)
Out[418]: array([False, True, False, True], dtype=bool)
如果线条的长度不同,那么这个array
就不会是二维的。它将改为包含列表的 1d。
正如评论中所建议的那样,我可以从整个字符串中创建一个数组,然后使用 view
到 'divide' 将它们转换为字符。
loadtxt
带有 'non-functioning' 分隔符将创建一个二维数组,如:
In [434]: np.array([[x] for x in txt])
Out[434]:
array([['AAAAAAAAAAAA'],
['BB BBBBBBBBB'],
['CCCCCCCCCCCC'],
['DDDDDD DDDDD']],
dtype='|S12')
然后拆分成字符:
In [435]: np.array([[x] for x in txt]).view('S1')
Out[435]:
array([['A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A'],
['B', 'B', ' ', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B'],
['C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C'],
['D', 'D', 'D', 'D', 'D', 'D', ' ', 'D', 'D', 'D', 'D', 'D']],
dtype='|S1')
我建议您先读取文件,检查是否有空格,如果通过测试,您可以将其存储起来用于最终的数组构造。如果您要丢弃无效数据或直接抛出错误,则使用附加指令将其操作到数组中是没有意义的。
input_files = ['input0.txt', 'input1.txt', 'input2.txt']
valid_data = []
for i in input_files:
with open(i, 'r') as f:
data = f.read()
if ' ' not in data:
valid_data.append([list(s) for s in data.split('\n')])
else:
print 'Invalid data in file {}. File will be ignored.'.format(i)
result = np.array(valid_data)
代码在遇到无效文件时打印警告。如果你真的想抛出一个错误,它会停止整个过程并且不会构造数组。为此,只需将打印的警告消息替换为
raise ValueError('Invalid data in file {}.'.format(i))
请注意,此代码假定所有文本文件都具有相同的行数和列数。如果情况并非如此,请说明您希望如何处理。
我们如何在 data
列表中存储字符串的简短说明。
如果您有一个列表列表并将其传递给一个数组,它将创建该列表列表的二维数组。例如,
>>> data = [['A', 'A', 'A'], ['B', 'B', 'B']]
>>> np.array(data)
array([['A', 'A', 'A'],
['B', 'B', 'B']],
dtype='|S1')
在这里,列表的成员数与文件中的行数一样多,子列表包含列数据。因此,如果我们得到一个列表列表的列表,其中我们有每个文件的列表,当我们将它传递给数组时,我们将拥有所需的维度。在您的示例中,对于每个文件 70 行和 50 列的 200 个文件,我们将得到 (200, 70, 50).
当我们一次性读取一个文件的内容时,它们是'AAA\nBBB'
的形式,那么我们如何将它变成[['A', 'A', 'A'], ['B', 'B', 'B']]
?
>>> data = 'AAA\nBBB'
>>> data.split('\n')
['AAA', 'BBB']
>>> [list(s) for s in data.split('\n')]
[['A', 'A', 'A'], ['B', 'B', 'B']]
我有一系列特定格式的文本文件。例如,file.txt
如下所示,形状为 50 列字母和 70 行文本:
AAAAAAAAAAAA
BBBBBBBBBBBB
CCCCCCCCCCCC
DDDDDDDDDDDD
我想将以下内容放入一个 numpy 数组中,然后进行操作。这个数组将有一定的维度。形状类似于 50 列字母,70 行文本,例如形状(70,50)。但是,某些文本文件是 "missing letters"。有问题的文件看起来像这样
AAAAAAAAAAAA
BB BBBBBBBBB
CCCCCCCCCCCC
DDDDDD DDDDD
我想检查是否存在任何 "spaces",并抛出错误。是否有处理 numpy 数组的标准方法?我是在将文本输入数组之前还是之后执行此操作?
我可以对多个文件执行此操作吗?也就是说,如果我输入 200 个文件,最终结果是一个形状为 (200,70,50)
的 numpy 数组。
对于大部分工作,您不需要 numpy
。下面的代码将输入文件读入列表,每个元素将是输入文件的一行(删除尾随换行符)。然后它创建一个相同长度的列表,每个元素都表示给定的字符串是否小于 space。如果其中任何一个是False
,那么你就有问题了,你可以随意处理这个案例。否则 space-less 条目被读入字符串类型 numpy.ndarray
.
import numpy as np
#read data into list "lines"
with open('input.inp') as f:
lines = [line.rstrip('\n') for line in f]
#check ones with spaces
nospaces = [not ' ' in line for line in lines]
#throw an error here if you will
if not all(nospaces):
print('Uh-oh!')
#or just ignore the ones contaning a space and put the rest into an ndarray
goodlines = np.array(lines)[np.array(nospaces)] #the only numpy-specific part
示例input.inp
:
asfasf asfasfsa
asffsafsafa
asfafsafs afa
faaffasaff
fasafasffas
afssfafs asafsas
输出:
In [1131]: run foo.py
Uh-oh!
In [1132]: lines
Out[1132]:
['asfasf asfasfsa',
'asffsafsafa',
'asfafsafs afa',
'faaffasaff',
'fasafasffas',
'afssfafs asafsas']
In [1133]: goodlines
Out[1133]:
array(['asffsafsafa', 'faaffasaff', 'fasafasffas'],
dtype='|S16')
注意最后输出的是"16-character string"类型,因为我们先把list变成了数组,然后把不需要的部分扔掉了。通过较小的工作,您可以根据自己的喜好定制此解决方案,并且您的示例似乎也表明您的输入行具有相同的长度(在这种情况下,结果数组将具有最佳 dtype
)。
让我们用文本行列表模拟您的文件:
In [401]: txt="""\
AAAAAAAAAAAA
BB BBBBBBBBB
CCCCCCCCCCCC
DDDDDD DDDDD
"""
In [402]: txt=txt.splitlines()
In [403]: txt
Out[403]: ['AAAAAAAAAAAA', 'BB BBBBBBBBB', 'CCCCCCCCCCCC', 'DDDDDD DDDDD']
如何将其加载到数组中?我们经常使用 loadtxt
,但那是针对数据列
In [404]: np.loadtxt(txt,dtype=str)
Out[404]:
array(['AAAAAAAAAAAA', 'BB', 'CCCCCCCCCCCC', 'DDDDDD'],
dtype='|S12')
没用。
让我们split
在这些方面
In [410]: [x.split() for x in txt]
Out[410]: [['AAAAAAAAAAAA'], ['BB', 'BBBBBBBBB'], ['CCCCCCCCCCCC'], ['DDDDDD', 'DDDDD']]
包含 'white space' 的行变成包含超过 1 个术语的列表
In [411]: [len(x.split())>1 for x in txt]
Out[411]: [False, True, False, True]
所以有 2 行有错误。
我可以通过 list()
传递字符串,将 txt
变成每列一个字母的数组。这给出了 np.array
列表的列表,所有列表的长度都相同。行尾的 blank/whitespace 可能会导致问题。
In [414]: A=np.array([list(x) for x in txt])
In [415]: A
Out[415]:
array([['A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A'],
['B', 'B', ' ', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B'],
['C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C'],
['D', 'D', 'D', 'D', 'D', 'D', ' ', 'D', 'D', 'D', 'D', 'D']],
dtype='|S1')
我可以测试此数组的 ' '
个字符,例如:
In [418]: np.any(A==' ',axis=1)
Out[418]: array([False, True, False, True], dtype=bool)
如果线条的长度不同,那么这个array
就不会是二维的。它将改为包含列表的 1d。
正如评论中所建议的那样,我可以从整个字符串中创建一个数组,然后使用 view
到 'divide' 将它们转换为字符。
loadtxt
带有 'non-functioning' 分隔符将创建一个二维数组,如:
In [434]: np.array([[x] for x in txt])
Out[434]:
array([['AAAAAAAAAAAA'],
['BB BBBBBBBBB'],
['CCCCCCCCCCCC'],
['DDDDDD DDDDD']],
dtype='|S12')
然后拆分成字符:
In [435]: np.array([[x] for x in txt]).view('S1')
Out[435]:
array([['A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A'],
['B', 'B', ' ', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B'],
['C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C'],
['D', 'D', 'D', 'D', 'D', 'D', ' ', 'D', 'D', 'D', 'D', 'D']],
dtype='|S1')
我建议您先读取文件,检查是否有空格,如果通过测试,您可以将其存储起来用于最终的数组构造。如果您要丢弃无效数据或直接抛出错误,则使用附加指令将其操作到数组中是没有意义的。
input_files = ['input0.txt', 'input1.txt', 'input2.txt']
valid_data = []
for i in input_files:
with open(i, 'r') as f:
data = f.read()
if ' ' not in data:
valid_data.append([list(s) for s in data.split('\n')])
else:
print 'Invalid data in file {}. File will be ignored.'.format(i)
result = np.array(valid_data)
代码在遇到无效文件时打印警告。如果你真的想抛出一个错误,它会停止整个过程并且不会构造数组。为此,只需将打印的警告消息替换为
raise ValueError('Invalid data in file {}.'.format(i))
请注意,此代码假定所有文本文件都具有相同的行数和列数。如果情况并非如此,请说明您希望如何处理。
我们如何在 data
列表中存储字符串的简短说明。
如果您有一个列表列表并将其传递给一个数组,它将创建该列表列表的二维数组。例如,
>>> data = [['A', 'A', 'A'], ['B', 'B', 'B']]
>>> np.array(data)
array([['A', 'A', 'A'],
['B', 'B', 'B']],
dtype='|S1')
在这里,列表的成员数与文件中的行数一样多,子列表包含列数据。因此,如果我们得到一个列表列表的列表,其中我们有每个文件的列表,当我们将它传递给数组时,我们将拥有所需的维度。在您的示例中,对于每个文件 70 行和 50 列的 200 个文件,我们将得到 (200, 70, 50).
当我们一次性读取一个文件的内容时,它们是'AAA\nBBB'
的形式,那么我们如何将它变成[['A', 'A', 'A'], ['B', 'B', 'B']]
?
>>> data = 'AAA\nBBB'
>>> data.split('\n')
['AAA', 'BBB']
>>> [list(s) for s in data.split('\n')]
[['A', 'A', 'A'], ['B', 'B', 'B']]