2009-08-10 2 views
3

Я новичок в python, и у меня есть проблема. У меня есть некоторые измеренные данные, сохраненные в txt-файле. данные разделены с закладками, он имеет такую ​​структуру:создать массив из txt-файла

0 0 -11.007001 -14.222319 2.336769 

Я всегда 32 точек данных за моделирование (0,1,2, ..., 31) и у меня есть 300 моделирования (0,1, 2 ..., 299), поэтому данные сначала сортируются с количеством симуляций, а затем числом точки данных.

Первый столбец - номер модели, второй столбец - номер точки данных, а остальные 3 столбца - координаты x, y, z.

Я хотел бы создать 3D-массив, первое измерение должно быть числом моделирования, второе - числом точек данных, а третье - тремя координатами.

Я уже начал немного, и вот что у меня до сих пор:

## 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]) 

, но я не знаю, как совместить эти 2 списка и этот один массив.

в конце концов, я хотел бы иметь что-то вроде этого:

Array = [simnum] [num_dat_point] [хуг]

спасибо за вашу помощь.

Надеюсь, вы понимаете мою проблему, это моя первая публикация на форуме python, поэтому, если я сделал что-то не так, я сожалею об этом.

еще раз спасибо

+3

Это не просто питон форум, я добавил питона тег так нужные люди, скорее всего, чтобы увидеть ваш вопрос и изменил формат вверху, чтобы резюме было более информативным для людей, смотрящих на список всех вопросов. –

ответ

2

вы можете комбинировать их с zip function, например, так:

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

Вы говорите свой итерационный пример «[избегает] понимания списков вообще», но вы используете его во втором - к последней строке. – JAB

+0

, и вы не видите, какая разница между моим использованием lc и OPs? – SilentGhost

+0

@Cat: 'map (float, lst [2:])' будет делать. –

2

Согласно zen python, квартира лучше, чем вложенная. Я просто использую дикт.

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) 
+0

Вы забыли преобразовать данные в int или поплавать соответственно. –

+0

@John Machin: исправлено – nosklo

+0

Не исправлено; ужасный QUOTE_NONNUMERIC трюк неявно преобразует ** ВСЕ ** данные OP для плавания. –

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() 

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

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

+0

greg - в какой версии python вы используете, что функция csv.reader принимает аргумент в отношении деминера? Мой python 2.6 этого не делает, добавлен ли он в python 3? – Petriborg

+0

Petriborg - я использую версию Python 2.5.2. Это также описано здесь: http://docs.python.org/library/csv.html – Greg

+1

@Petriborg, @Greg: он работает лучше, если вы правильно наделили разделитель. – jcdyer

1

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

Вам необходимо сначала измерить массив до соответствующих размеров. t должен быть массив не менее 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

каждый симулятор имеет ровно столько же очков. – steffen

+0

хорошо. Тогда этот код должен работать нормально, скажем, t = [[[0,0,0] для i в диапазоне (32)] для j в диапазоне (300)] –

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.

1

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

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

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

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

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

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

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 возвращает словарь, который вы можете указать с номером модели и номером набора данных; например,

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

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

print d.get((0, 0)) 

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

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

+0

я указал свое сообщение. У меня всегда 32 точки данных для моделирования (0,1,2, ..., 31), и у меня есть 300 симуляций (0,1,2 ..., 299), поэтому данные сначала сортируются с номером моделирования, а затем номер точки данных. Надеюсь, что помощь и благодарность за помощь, это действительно хорошая помощь. Извините за мой несходный способ публикации, но я постараюсь сделать это лучше в будущем. Еще раз спасибо – steffen

+0

NP, и я вижу, что вы уже приняли ответ, так что это должно означать, что ответ решил вашу проблему, поэтому я рад за вас! –

0

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

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

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]

Смежные вопросы