如何查找并解决加载.txt 文件时发生的IndexError 的原因? Python
How to find the cause of and solve an IndexError that occurs when loading a .txt file ? Python
我正在尝试训练用于机器翻译的序列到序列模型。我使用一个公开可用的 .txt
数据集,其中包含两列英语到德语的阶段(每行一对,用一个选项卡分隔语言):http://www.manythings.org/anki/deu-eng.zip 这很好用。但是,我 运行 在尝试使用我自己的数据集时遇到了问题。
我自己的 DataFrame
是这样的:
Column 1 Column 2
0 English a German a
1 English b German b
2 English c German c
3 English d German d
4 ... ...
为了在同一个脚本中使用它,我将这个 DataFrame
保存到一个 .txt
文件中,如下所示(目的是再次每行一对,用一个选项卡分隔语言):
df.to_csv("dataset.txt", index=False, sep='\t')
问题出现在清理数据的代码中:
# load doc into memory
def load_doc(filename):
# open the file as read only
file = open(filename, mode='rt', encoding='utf-8')
# read all text
text = file.read()
# close the file
file.close()
return text
# split a loaded document into sentences
def to_pairs(doc):
lines = doc.strip().split('\n')
pairs = [line.split('\t') for line in lines]
# clean a list of lines
def clean_pairs(lines):
cleaned = list()
# prepare regex for char filtering
re_print = re.compile('[^%s]' % re.escape(string.printable))
# prepare translation table for removing punctuation
table = str.maketrans('', '', string.punctuation)
for pair in lines:
clean_pair = list()
for line in pair:
# normalize unicode characters
line = normalize('NFD', line).encode('ascii', 'ignore')
line = line.decode('UTF-8')
# tokenize on white space
line = line.split()
# convert to lowercase
line = [word.lower() for word in line]
# remove punctuation from each token
line = [word.translate(table) for word in line]
# remove non-printable chars form each token
line = [re_print.sub('', w) for w in line]
# remove tokens with numbers in them
line = [word for word in line if word.isalpha()]
# store as string
clean_pair.append(' '.join(line))
# print(clean_pair)
cleaned.append(clean_pair)
# print(cleaned)
print(array(cleaned))
return array(cleaned) # something goes wrong here
# save a list of clean sentences to file
def save_clean_data(sentences, filename):
dump(sentences, open(filename, 'wb'))
print('Saved: %s' % filename)
# load dataset
filename = 'data/dataset.txt'
doc = load_doc(filename)
# split into english-german pairs
pairs = to_pairs(doc)
# clean sentences
clean_pairs = clean_pairs(pairs)
# save clean pairs to file
save_clean_data(clean_pairs, 'english-german.pkl')
# spot check
for i in range(100):
print('[%s] => [%s]' % (clean_pairs[i,0], clean_pairs[i,1]))
最后一行抛出以下错误:
IndexError Traceback (most recent call last)
<ipython-input-2-052d883ebd4c> in <module>()
72 # spot check
73 for i in range(100):
---> 74 print('[%s] => [%s]' % (clean_pairs[i,0], clean_pairs[i,1]))
75
76 # load a clean dataset
IndexError: too many indices for array
一件奇怪的事情是,标准数据集与我自己的数据集的以下行的输出不同:
# Standard dataset:
return array(cleaned)
[['hi' 'hallo']
['hi' 'gru gott']
['run' ‘lauf’]]
# My own dataset:
return array(cleaned)
[list(['hi' 'hallo'])
list(['hi' 'gru gott'])
list(['run' ‘lauf’])]
任何人都可以解释问题是什么以及如何解决这个问题吗?
clean_pairs
是 list
个 list
。核心 Python 语言没有正式的多维数组概念,因此您使用的语法 clean_pairs[i,0]
不起作用。应该是clean_pairs[i][0]
。
您可能从使用 Pandas 得到了灵感,它使用了支持这种索引风格的更复杂的 n-d 数组数据结构。
虽然我对你的代码感到困惑。看起来您正在将数据框保存到 TSV 文件(制表符分隔),然后手动解析 TSV 并对其执行文本转换?这有很多问题:
- 正如您使用库编写 TSV 文件一样,您也应该使用库来读取 TSV 文件。 CSV/TSV reader 将 return 您的数据行以预解析的数据结构直接返回给您。
- AFAICT,您可以对内存中的数据进行所有此类过滤,而无需首先写入中间文件。
至少在您发布的代码中还有一些其他问题。例如,您的 to_pairs
函数(这又是您应该留给图书馆的东西,如果有的话)没有 return 任何东西。
我正在尝试训练用于机器翻译的序列到序列模型。我使用一个公开可用的 .txt
数据集,其中包含两列英语到德语的阶段(每行一对,用一个选项卡分隔语言):http://www.manythings.org/anki/deu-eng.zip 这很好用。但是,我 运行 在尝试使用我自己的数据集时遇到了问题。
我自己的 DataFrame
是这样的:
Column 1 Column 2
0 English a German a
1 English b German b
2 English c German c
3 English d German d
4 ... ...
为了在同一个脚本中使用它,我将这个 DataFrame
保存到一个 .txt
文件中,如下所示(目的是再次每行一对,用一个选项卡分隔语言):
df.to_csv("dataset.txt", index=False, sep='\t')
问题出现在清理数据的代码中:
# load doc into memory
def load_doc(filename):
# open the file as read only
file = open(filename, mode='rt', encoding='utf-8')
# read all text
text = file.read()
# close the file
file.close()
return text
# split a loaded document into sentences
def to_pairs(doc):
lines = doc.strip().split('\n')
pairs = [line.split('\t') for line in lines]
# clean a list of lines
def clean_pairs(lines):
cleaned = list()
# prepare regex for char filtering
re_print = re.compile('[^%s]' % re.escape(string.printable))
# prepare translation table for removing punctuation
table = str.maketrans('', '', string.punctuation)
for pair in lines:
clean_pair = list()
for line in pair:
# normalize unicode characters
line = normalize('NFD', line).encode('ascii', 'ignore')
line = line.decode('UTF-8')
# tokenize on white space
line = line.split()
# convert to lowercase
line = [word.lower() for word in line]
# remove punctuation from each token
line = [word.translate(table) for word in line]
# remove non-printable chars form each token
line = [re_print.sub('', w) for w in line]
# remove tokens with numbers in them
line = [word for word in line if word.isalpha()]
# store as string
clean_pair.append(' '.join(line))
# print(clean_pair)
cleaned.append(clean_pair)
# print(cleaned)
print(array(cleaned))
return array(cleaned) # something goes wrong here
# save a list of clean sentences to file
def save_clean_data(sentences, filename):
dump(sentences, open(filename, 'wb'))
print('Saved: %s' % filename)
# load dataset
filename = 'data/dataset.txt'
doc = load_doc(filename)
# split into english-german pairs
pairs = to_pairs(doc)
# clean sentences
clean_pairs = clean_pairs(pairs)
# save clean pairs to file
save_clean_data(clean_pairs, 'english-german.pkl')
# spot check
for i in range(100):
print('[%s] => [%s]' % (clean_pairs[i,0], clean_pairs[i,1]))
最后一行抛出以下错误:
IndexError Traceback (most recent call last)
<ipython-input-2-052d883ebd4c> in <module>()
72 # spot check
73 for i in range(100):
---> 74 print('[%s] => [%s]' % (clean_pairs[i,0], clean_pairs[i,1]))
75
76 # load a clean dataset
IndexError: too many indices for array
一件奇怪的事情是,标准数据集与我自己的数据集的以下行的输出不同:
# Standard dataset:
return array(cleaned)
[['hi' 'hallo']
['hi' 'gru gott']
['run' ‘lauf’]]
# My own dataset:
return array(cleaned)
[list(['hi' 'hallo'])
list(['hi' 'gru gott'])
list(['run' ‘lauf’])]
任何人都可以解释问题是什么以及如何解决这个问题吗?
clean_pairs
是 list
个 list
。核心 Python 语言没有正式的多维数组概念,因此您使用的语法 clean_pairs[i,0]
不起作用。应该是clean_pairs[i][0]
。
您可能从使用 Pandas 得到了灵感,它使用了支持这种索引风格的更复杂的 n-d 数组数据结构。
虽然我对你的代码感到困惑。看起来您正在将数据框保存到 TSV 文件(制表符分隔),然后手动解析 TSV 并对其执行文本转换?这有很多问题:
- 正如您使用库编写 TSV 文件一样,您也应该使用库来读取 TSV 文件。 CSV/TSV reader 将 return 您的数据行以预解析的数据结构直接返回给您。
- AFAICT,您可以对内存中的数据进行所有此类过滤,而无需首先写入中间文件。
至少在您发布的代码中还有一些其他问题。例如,您的 to_pairs
函数(这又是您应该留给图书馆的东西,如果有的话)没有 return 任何东西。