Я жаловался на это поведение для изменения имени поля до numpy issue tracker и списка рассылки. Он также вырос в severalpreviousquestions на SO.
В самом деле, по умолчанию np.genfromtxt
будет изменять имена полей, даже если указать их непосредственно, передавая список строк в качестве names=
параметра:
import numpy as np
from io import BytesIO
s = '[5],name with spaces,(x-1)!\n1,2,3\n4,5,6'
x = np.genfromtxt(BytesIO(s), delimiter=',', names=True)
print(repr(x))
# array([(1.0, 2.0, 3.0), (4.0, 5.0, 6.0)],
# dtype=[('5', '<f4'), ('name_with_spaces', '<f4'), ('x1\n1', '<f4')])
names = s.split(',')[:3]
x = np.genfromtxt(BytesIO(s), delimiter=',', skip_header=1, names=names)
print(repr(x))
# array([(1.0, 2.0, 3.0), (4.0, 5.0, 6.0)],
# dtype=[('5', '<f4'), ('name_with_spaces', '<f4'), ('x1\n1', '<f4')])
Это происходит, несмотря на то, что имена полей, содержащих не алфавитно-цифровой персонажи совершенно законны:
x2 = np.empty(2, dtype=dtype)
x2[:] = [(1.0, 2.0, 3.0), (4.0, 5.0, 6.0)]
print(repr(x2))
# array([(1.0, 2.0, 3.0), (4.0, 5.0, 6.0)],
# dtype=[('[5]', '<f4'), ('name with spaces', '<f4'), ('(x-1)!\n1', '<f4')])
Логика этого поведения ускользает от меня.
Как вы уже видели, проходя None
как deletechars=
аргумент не достаточно, чтобы не допустить этого, так как этот аргумент инициализируется внутренне набор символов по умолчанию в numpy._iotools.NameValidator
.
Однако, вы можете передать пустую последовательность вместо:
x = np.genfromtxt(BytesIO(s), delimiter=',', names=True, deletechars='')
print(repr(x))
# array([(1.0, 2.0, 3.0), (4.0, 5.0, 6.0)],
# dtype=[('[5]', '<f8'), ('name_with_spaces', '<f8'), ('(x-1)!', '<f8')])
Это может быть пустая строка, список, кортеж и т.д. Это не имеет значения, пока его длина равна нулю.
Спасибо, ali_m. Я видел это решение в трекере ошибок [здесь] (https://github.com/numpy/numpy/issues/2509). @unutbu, рассматривал исправление после факта, но пустой параметр намного проще. Будет тест, а затем принять ответ. – krosbonz
Эти символы могут выглядеть в формате dtype с структурированным массивом, но не как имена атрибутов для повторной проверки. Я вижу такое же напряжение в 'argparse' - вы даете пользователю достаточно веревки, чтобы повесить себя? – hpaulj
@hpaulj Nope - они также легальны для повторных вычислений (хотя, конечно, вы не можете использовать синтаксис '.attribute' для доступа к ним). Независимо от того, должны ли они быть * законными, это еще один вопрос, но я считаю, что 'np.genfromtxt' не должен произвольно испортить имена юридических полей. –