it-roy-ru.com

Импорт данных и имен переменных из текстового файла в Python

У меня есть текстовый файл, содержащий данные моделирования (60 столбцов, 100 тыс. Строк):

a  b   c  
1  11 111
2  22 222
3  33 333
4  44 444

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

Мне нужно использовать все эти переменные с их данными в Python для дальнейших расчетов. Например, когда я вставляю:

print(b)

Мне нужно получить значения из второго столбца. 

Я знаю, как импортировать данные:

data=np.genfromtxt("1.txt", unpack=True, skiprows = 1)

Назначьте переменные «вручную»:

a,b,c=np.genfromtxt("1.txt", unpack=True, skiprows = 1)

Но у меня проблемы с получением имен переменных: 

reader = csv.reader(open("1.txt", "rt"))
for row in reader: 
   list.append(row)
variables=(list[0])  

Как я могу изменить этот код, чтобы получить все имена переменных из первой строки и присвоить их импортированным массивам? 

4
Michal

Вместо того, чтобы пытаться присваивать имена, вы можете подумать об использовании ассоциативного массива , который известен в Python как dict , для хранения ваших переменных и их значений. Код может выглядеть примерно так (заимствуя из документации csv ):

import csv
with open('1.txt', 'rt') as f:
  reader = csv.reader(f, delimiter=' ', skipinitialspace=True)

  lineData = list()

  cols = next(reader)
  print(cols)

  for col in cols:
    # Create a list in lineData for each column of data.
    lineData.append(list())


  for line in reader:
    for i in xrange(0, len(lineData)):
      # Copy the data from the line into the correct columns.
      lineData[i].append(line[i])

  data = dict()

  for i in xrange(0, len(cols)):
    # Create each key in the dict with the data in its column.
    data[cols[i]] = lineData[i]

print(data)

Затем data содержит все ваши переменные, к которым можно получить доступ через data['varname'].

Так, например, вы можете сделать data['a'], чтобы получить список ['1', '2', '3', '4'], учитывая входные данные, указанные в вашем вопросе.

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

2
andyg0808

Ответ: вы не хотите этого делать.

Словари предназначены именно для этой цели: структура данных, которую вы на самом деле хотите, будет выглядеть примерно так:

data = {
    "a": [1, 2, 3, 4],
    "b": [11, 22, 33, 44],
    "c": [111, 222, 333, 444],
}

... к которому вы можете легко получить доступ, например, используя data["a"].

Можно делать то, что вы хотите, но обычный способ - это хак, который основан на том факте, что Python использует (drumroll) a dict для хранения переменных - и так как ваш код не будет Если вы знаете имена этих переменных, вы будете застревать, используя словарный доступ, чтобы получить их ... так что вы могли бы просто использовать словарь в первую очередь.

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

Если вы еще не уверены, вот хорошая статья на эту тему:

Глупые идеи Python: почему вы не хотите динамически создавать переменные

2
Zero Piraeus

Вот простой способ конвертировать .txt файл имен переменных и данных в массивы NumPy. 

D = np.genfromtxt('1.txt',dtype='str')    # load the data in as strings
D_data = np.asarray(D[1::,:],dtype=float) # convert the data to floats
D_names = D[0,:]                          # save a list of the variable names

for i in range(len(D_names)):
    key = D_names[i]                      # define the key for this variable 
    val = D_data[:,i]                     # set the value for this variable 
    exec(key + '=val')                    # build the variable  code here

Мне нравится этот метод, потому что за ним легко следовать и просто поддерживать. Мы можем сжать этот код следующим образом:

D = np.genfromtxt('1.txt',dtype='str')     # load the data in as strings
for i in range(D.shape[1]):
    val = np.asarray(D[1::,i],dtype=float) # set the value for this variable 
    exec(D[0,i] + '=val')                  # build the variable 

Оба кода делают одно и то же, возвращая массивы NumPy с именами a, b и c с соответствующими данными. 

0
Austin Downey

Благодаря @ andyg0808 и @Zero Piraeus я нашел другое решение. Для меня самое подходящее - использование библиотеки анализа данных Pandas.

   import pandas as pd

   data=pd.read_csv("1.txt",
           delim_whitespace=True,
           skipinitialspace=True)

  result=data["a"]*data["b"]*3
  print(result)

  0     33
  1    132
  2    297
  3    528

... где 0,1,2,3 - индекс строки.

0
Michal