create an array from a txt file

Refresh

December 2018

Views

4.9k time

3

I'm new in python and I have a problem. I have some measured data saved in a txt file. the data is separated with tabs, it has this structure:

0   0   -11.007001  -14.222319  2.336769

i have always 32 datapoints per simulation (0,1,2,...,31) and i have 300 simulations (0,1,2...,299), so the data is sorted at first with the number of simulation and then the number of the data point.

The first column is the simulation number, the second column is the data point number and the other 3 columns are the x,y,z coordinates.

I would like to create a 3d array, the first dimension should be the simulation number, the second the number of the datapoint and the third the three coordinates.

I already started a bit and here is what I have so far:

## read file
coords = [x.split('\t') for x in
          open(f,'r').read().replace('\r','')[:-1].split('\n')]
## extract the information you want
simnum = [int(x[0]) for x in coords]
npts = [int(x[1]) for x in coords]
xyz = array([map(float,x[2:]) for x in coords])

but I don't know how to combine these 2 lists and this one array.

in the end i would like to have something like this:

array = [simnum][num_dat_point][xyz]

thanks for your help.

I hope you understand my problem, it's my first posting in a python forum, so if I did anything wrong, I'm sorry about this.

thanks again

9 answers

1

по существу, трудность заключается в том, что происходит, если разные моделирования имеют разное количество очков.

Таким образом , вы будете нуждаться в размерности массива к соответствующим размерам первым. т должен быть массив , по крайней мере max(simnum) x max(npts) x 3. Чтобы избежать путаницы , вы должны инициализировать с не-число, это позволит вам увидеть недостающие точки.

затем использовать что-то вроде

for x in coords:
  t[int(x[0])][int(x[1])][0]=float(x[3])
  t[int(x[0])][int(x[1])][1]=float(x[4])
  t[int(x[0])][int(x[1])][2]=float(x[5])

это то, что вы имели в виду?

0

Во-первых, я бы указать на то, что ваша первая точка данных, как представляется, индекс, и интересно, если данные, поэтому важно или нет, но в зависимости от того :-)

def parse(line):
    mch = re.compile('^(\d+)\s+(\d+)\s+([-\d\.]+)\s+([-\d\.]+)\s+([-\d\.]+)$')
    m = mch.match(line)
    if m:
        l = m.groups()
        (idx,data,xyz) = (int(l[0]),int(l[1]), map(float, l[2:]))
        return (idx, data, xyz)
    return None

finaldata = []
file = open("data.txt",'r')
for line in file:
    r = parse(line)
    if r is not None:
        finaldata.append(r)

Окончательные данные должны иметь выход вдоль линий:

[(0, 0, [-11.007001000000001, -14.222319000000001, 2.3367689999999999]),
 (1, 0, [-11.007001000000001, -14.222319000000001, 2.3367689999999999]),
 (2, 0, [-11.007001000000001, -14.222319000000001, 2.3367689999999999]),
 (3, 0, [-11.007001000000001, -14.222319000000001, 2.3367689999999999]),
 (4, 0, [-11.007001000000001, -14.222319000000001, 2.3367689999999999])]

Это должно быть довольно прочным о работе ж / пробельных вопросы (вкладки пространства этажерки) ...

Я также задаюсь вопросом, насколько большой ваши файлы данных, шахты, как правило, большой, чтобы быть в состоянии обработать их в куски или группы становятся все более важными ... В любом случае это будет работать в Python 2.6.

2

Вы можете комбинировать их с zipфункцией , например , так:

for sim, datapoint, x, y, z in zip(simnum, npts, *xyz):
    # do your thing

или вы могли бы избежать списковых вообще и просто перебирать строки файла:

for line in open(fname):
    lst = line.split('\t')
    sim, datapoint = int(lst[0]), int(lst[1])
    x, y, z = [float(i) for i in lst[2:]]
    # do your thing

разобрать одну строку, вы могли (и должны) сделать следующее:

coords = [x.split('\t') for x in open(fname)]
0

Вы уверены, что 3D-массив, что вы хотите? Представляется более вероятным, что вы хотите 2d массива, где число моделирования является одним из аспектов, точка данных является вторым, а затем значения, хранящееся в этом месте является координатой.

Этот код даст вам это.

data = []
for coord in coords:
    if coord[0] not in data:
        data[coord[0]] = []
    data[coord[0]][coord[1]] = (coord[2], coord[3], coord[4])

Чтобы получить координаты при моделировании 7 точек данных 13, вобще данные [7] [13]

1

Вы можете использовать много различных видов контейнеров для ваших целей, но ни один из них не имеют в arrayкачестве безоговорочного имени - Python имеет модуль , arrayкоторый можно импортировать из стандартной библиотеки, но array.arrayтип слишком ограничен для ваших целей (1-D только и с элементарными типами , как содержание); есть популярное расширение третьей стороной известный как numpy, который имеет мощный numpy.arrayтип, который вы могли бы использовать , если вы уже загрузили и установили расширение - но , как вы никогда даже не один раз упомянуть , numpyя сомневаюсь , что это то , что вы имеете в виду; соответствующие встроенные типы listиdict, Я предполагаю, что вы хотите какой-либо контейнер вообще - но если вы могли бы научиться использовать точную терминологию в будущем, что будет в значительной степени помочь вам и любой, кто пытается помочь (скажем, список, когда вы имеете в виду список, массив только тогда, когда Вы имеешь в виду массив, «контейнер», когда вы не уверены о том, что контейнер для использования, и так далее).

Я предлагаю вам взглянуть на csvмодуле в стандартной библиотеке для более надежного способа чтения данных, но это отдельный вопрос. Начнем с того, когда у вас есть coordsсписок списков 5 строк каждый, каждый подсписок со строками , представляющих два Интса следует три поплавков. Еще два ключевых аспекта должен быть указан ...

Одним из ключевых аспектов вы не говорите нам о: это список отсортирован в какой-то существенным образом? есть, в частности, некоторые важный заказ вы хотите сохранить? Как вы даже не упоминает ни вопрос, я должен буду считать, так или иначе, и я буду считать, что не существует какой-либо гарантируется и не имеет смысла порядка; но, не повторяется (каждая пара моделирования / чисел DataPoint не допускается, чтобы встречаться несколько раз).

Второй ключевой аспект: есть такое же количество точек данных в моделировании, в порядке возрастания (0, 1, 2, ...), или в том , что не обязательно так (и кстати, являются сами по себе моделирования пронумерованы 0, 1, 2 , ...)? Опять же , понятия не от вас на этой незаменимой части спецификации - обратите внимание , сколько предположений вы заставляете потенциальных помощников , чтобы сделать, просто не говорит нам о таких явно важных аспектах. Не позволяйте людям , которые хотят , чтобы помочь вам споткнуться в темноте: скорее, научиться задавать вопросы умный способ - это сэкономит невыразимое количество времени для себя и потенциальных помощников, идать вам более высокого качества и более уместную помощь, поэтому, почему бы не сделать это? Во всяком случае, вынужден сделать еще одно предположение, я буду не считать вообще ничего известно о количестве моделирования, ни о numers из точек данных в каждой модели.

При этих допущениях dictвыступают как единственные разумные структуры использовать для внешнего контейнера: словарь, ключ которого кортеж из двух элементов, количество моделирования затем DataPoint числа в моделировании. Значения , а также может быть кортеж тоже (с тремя поплавками каждый), так как это действительно кажется , что у вас есть ровно три координаты в каждой строке.

С учетом всех этих предположений ...:

def make_container(coords):
  result = dict()
  for s, d, x, y, z in coords:
    key = int(s), int(d)
    value = float(x), float(y), float(z)
    result[key] = value
  return result

Это всегда лучше, и быстро, чтобы иметь всю значительную коду в defотчетности (т.е. как функции , которые можно назвать, возможно , с соответствующими аргументами), поэтому я представляю это так. make_containerвозвращает словарь , который вы можете обратиться с номером моделирования и номер DataPoint; например,

d = make_container(coords)
print d[0, 0]

напечатает х, у, г для дп 0 из сима 0, предполагая, что она существует (вы получите ошибку, если такая комбинация сим / дп не существует). dicts имеют много полезных методов, например, изменяя оператор печати выше для

print d.get((0, 0))

(да, вы делаете нужно двойной круглые скобки здесь - внутренние, чтобы кортеж, наружные позвонить getс этого кортежа , как его единственный аргумент), вы видите None, а не получить исключение, если бы не было такой сим / дп combinarion как (0, 0).

Если вы можете редактировать свой вопрос, чтобы сделать ваши данные более точными (возможно, в том числе некоторых указаний способов вы планируете использовать полученный контейнер, а также различные ключевые аспекты я перечисленные выше), я мог бы также быть в состоянии точно настроить этот совет, чтобы соответствовать вашим потребностям и обстоятельствам гораздо лучше, поэтому я настоятельно рекомендую вам сделать это (и так, возможно, когда-либо другой ответчик, в отношении их собственного совета!) - заранее спасибо за помощь нам помочь вам! -)

2

Это кажется хорошей возможностью использовать itertools.groupby.

import itertools
import csv
file = open("data.txt")
reader = csv.reader(file, delimiter='\t')
result = []
for simnumberStr, rows in itertools.groupby(reader, key=lambda t: t[0]):
    simData = []
    for row in rows:
        simData.append([float(v) for v in row[2:]])
    result.append(simData)
file.close()

Это позволит создать 3 размерных список с именем «результат». Первого индекса является номером моделирования, а второй индекс является индексом данных в пределах этого моделирования. Значение представляет собой список целых чисел, содержащих х, у и г координат.

Обратите внимание, что это предполагает, что данные уже отсортированы по количеству моделирования и количества данных.

2

Это кажется хорошей возможностью использовать itertools.groupby.

import itertools
import csv
file = open("data.txt")
reader = csv.reader(file, delimiter='\t')
result = []
for simnumberStr, rows in itertools.groupby(reader, key=lambda t: t[0]):
    simData = []
    for row in rows:
        simData.append([float(v) for v in row[2:]])
    result.append(simData)
file.close()

Это позволит создать 3 размерных список с именем «результат». Первого индекса является номером моделирования, а второй индекс является индексом данных в пределах этого моделирования. Значение представляет собой список целых чисел, содержащих х, у и г координат.

Обратите внимание, что это предполагает, что данные уже отсортированы по количеству моделирования и количества данных.

2

Согласно дзэн питона, плоский лучше, чем вложенное. Я бы просто использовать Dict.

import csv
f = csv.reader(open('thefile.csv'), delimiter='\t',
               quoting=csv.QUOTE_NONNUMERIC)

result = {}
for simn, dpoint, c1, c2, c3 in f:
    result[simn, dpoint] = c1, c2, c3

# pretty-prints the result:
from pprint import pprint
pprint(result)
2

Это кажется хорошей возможностью использовать itertools.groupby.

import itertools
import csv
file = open("data.txt")
reader = csv.reader(file, delimiter='\t')
result = []
for simnumberStr, rows in itertools.groupby(reader, key=lambda t: t[0]):
    simData = []
    for row in rows:
        simData.append([float(v) for v in row[2:]])
    result.append(simData)
file.close()

Это позволит создать 3 размерных список с именем «результат». Первого индекса является номером моделирования, а второй индекс является индексом данных в пределах этого моделирования. Значение представляет собой список целых чисел, содержащих х, у и г координат.

Обратите внимание, что это предполагает, что данные уже отсортированы по количеству моделирования и количества данных.