2015-10-20 3 views
2

Я нашел много способов ввода файлов csv с текстовыми записями в виде числовых массивов в Python, таких как this и this, но ни одна из них не была в моей ситуации, и никто не работал для меня. Я также не мог найти ответ в the manual из numpy или других распространенных инструментов для этого, но, возможно, он есть, и я просто не могу этого понять.Как установить строку в float-конвертеры для numpy genfromtxt

У меня есть данные в формате CSV, как это:

"experiment 1" 
"var1","var2","var3","var4","var5" 
"7","0","1","3","1" 
"8","4","3","1","1" 
"8","5","3","3","1" 
"8","6","3","3","3" 

Я попытался считывания данных с помощью

dataArray = np.genfromtxt('Input Data/'+fileName,delimiter=',',skiprows=2) 

и я также попытался добавить

.astype(np.float) 

до конца. Но то, что я в конечном итоге в любом случае:

[[ nan nan nan nan nan] 
[ nan nan nan nan nan] 
[ nan nan nan nan nan] 
[ nan nan nan nan nan]] 

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

converters = {3: lambda s: float(s or 0)} 

, и я действительно не могу сделать какой-либо смысл этого синтаксиса. Предполагая, что встроенные преобразователи могут обрабатывать мои данные, каков правильный синтаксис для записи параметра преобразователя для этого? Если конвертеры не могут делать то, что мне нужно, кто-нибудь знает, как читать эти данные? Я ожидал, что это будет очень просто, что я найду через 5 минут, но сейчас я потратил немного времени на это.

+0

Может быть, вы должны рассмотреть вопрос о переименовании на ваш вопрос, потому что я думаю, что это больше о том, как читать ваш файл данных в NumPy массив, правильно? Поплавковые преобразователи - это всего лишь одна возможность. –

ответ

3

Считывание данных с именами столбцов

Для использования np.genfromtext вы должны сначала прочитать файл в строку, удалить все " символы, а затем прочитать эту строку используя в cStringIO:

>>>import cStringIO 
>>>with open ("123", "r") as myfile: 
     data=myfile.read().replace('"', '') 
>>>np.genfromtxt(cStringIO.StringIO(data), skip_header=1, delimiter=",", names = True) 

array([(7.0, 0.0, 1.0, 3.0, 1.0), 
     (8.0, 4.0, 3.0, 1.0, 1.0), 
     (8.0, 5.0, 3.0, 3.0, 1.0), 
     (8.0, 6.0, 3.0, 3.0, 3.0)], 
     dtype=[('var1', '<f8'), ('var2', '<f8'), ('var3', '<f8'), ('var4', '<f8'), ('var5', '<f8')]) 

Вы также можете использовать pandas:

>>>pd.read_csv(file, header=0, skiprows = 1).as_matrix() 

    var1 var2 var3 var4 var5 
0  7  0  1  3  1 
1  8  4  3  1  1 
2  8  5  3  3  1 
3  8  6  3  3  3 

Чтение данных в без имен столбцов

Вы можете сначала прочитать файл в массив, содержащий строки:

a = np.genfromtxt('filename', skip_header=2, delimiter=",", dtype = 'str') 
print a 

, который дает:

[['"7"' '"0"' '"1"' '"3"' '"1"'] 
['"8"' '"4"' '"3"' '"1"' '"1"'] 
['"8"' '"5"' '"3"' '"3"' '"1"'] 
['"8"' '"6"' '"3"' '"3"' '"3"']] 

, а затем преобразовать его в поплавки с использованием numpy следующим образом:

a = np.char.strip(a, '"').astype(float) 
print a 

который дает

[[ 7. 0. 1. 3. 1.] 
[ 8. 4. 3. 1. 1.] 
[ 8. 5. 3. 3. 1.] 
[ 8. 6. 3. 3. 3.]] 

Вы также предложили использовать панда. Для того, чтобы прочитать его в панд DataFrame вы могли бы сделать:

import pandas as pd 
a = pd.read_csv('./test', header=None, skiprows = 2) 
print a 

, который дает:

0 1 2 3 4 
0 7 0 1 3 1 
1 8 4 3 1 1 
2 8 5 3 3 1 
3 8 6 3 3 3 
+1

Хорошо, это близко и проще в использовании, чем конвертер на колонку. Вот что на самом деле это: 'dataArray = np.char.strip (np.genfromtxt ('Input Data /' + fileName, skip_header = 2, delimiter =", ", dtype = None), '"') .astype (float) ', который объединяет две линии, которые у вас есть, и изменяет некоторые части, которые были не совсем правильными.Единственное, что возможно, заключается в том, что он также НЕ МОЖЕТ обрабатывать заголовки: вместо этого вместо этого следует использовать 'skip_header = 1, names = True,' возвращает 'TypeError: строковая операция для нестрочного массива', даже когда я повторно вставляю', deletechars = '"', dtype = 'str''. Сейчас я собираюсь избежать панд. –

+0

Хорошо, не знал, что вы также хотите прочитать имена. Я думаю, вы не можете сделать это с помощью genfromtxt, потому что у вашего файла есть разные разделители для имен столбцов и для записей данных. Возможно, вы можете сделать это с помощью 'pandas.read_csv', потому что вы можете указать несколько разделителей с помощью регулярных выражений. –

+1

Ах, реальные данные имеют соответствующие заголовки - имена переменных для каждого столбца. вопрос, чтобы отразить это. Это должно быть довольно нормальным явлением, поэтому я ожидаю, что 'genfromtxt' сможет обрабатывать его для человека, который знает, как он работает.' deletechars = '"'' должен действительно заботиться об этом , но, похоже, он ничего не делает. Может быть, лучше всего открыть csv как блок txt и удалить '' ', а затем запустить' genfromtxt'. –

0
this will print you first two columns in the file 
Since you have two headers you need to skip first to rows with next() 

with open("data.csv", 'r') as f: 
     r = csv.reader(f, delimiter=',') 
     next(r, None) # skip the header 
     next(r, None) # skip the header 
     for row in r: 
      print(row[0],row[1]) 

7 0 
8 4 
8 5 
8 6 
+0

Я считаю, что параметр 'skiprows = 2' должен обрабатывать это. –

+0

@AaronBramson вы имеете в виду np? это простой читатель csv, у него нет параметра skiprows, я только что просмотрел справку csv. по крайней мере, в python 3.5 no skiprows ... – LetzerWille

+0

да, в конце концов, это должен быть массив с несколькими числами, поэтому лучше всего использовать встроенные методы numpy для этого. И 'genfromtxt' должен быть правильным ... если я могу просто вычислить конвертеры. Другой альтернативой было бы удалить кавычки из файла csv перед чтением, но использование преобразователей должно быть более общим и, следовательно, предпочтительным. –

2

После долгих поисков и попыток и боевых действий мне удалось выяснить, как это сделать.

Во-первых, для удобства, я делаю формулу преобразования отдельно и вызывать его из внутри genfromtxt команды:

convert = lambda x: float(x.strip('"') or -999) 

Что это lambda function делает раздеться двойные кавычки символы из каждой записи (или если он пуст или nan установите его как -999), а затем преобразуйте запись в поплавок. Затем он переходит в genfromtext команду:

dataArray = np.genfromtxt('Input Data/'+fileName,delimiter=',',skip_header=2,converters={0: convert,1: convert,2: convert,3: convert,4: convert},dtype=None) 

Это работает для данного конкретного случая, но у него есть две проблемы: (1) вы должны указать конвертер для каждой колонки отдельно - я не мог найти способ указать «применить ко всем столбцам». Лучшим способом сделать это было бы использование итерационной функции, которая обрабатывает все столбцы и применяет преобразование ко всем из них ... тогда функция THAT будет определять, к какому столбцу применить ее. Я не знаю, как это сделать, если это возможно. Задача (2) заключается в том, что вы не можете читать в заголовках в комбинации с преобразователями. Например:

dataArray = np.genfromtxt('Input Data/'+fileName,delimiter=',',skip_header=1,names=True,converters={0: convert,1: convert,2: convert,3: convert,4: convert},dtype=None) 

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

Моей рекомендацией для кого-то, сталкивающейся с этой проблемой в будущем, является поиск другого метода для выполнения этой функции. Многие люди рекомендовали pandas для подобных задач в других вопросах, но я не знаю, лучше ли для этого случая. Пока это будет работать для меня, но в ближайшем будущем его нужно будет заменить более надежным считывателем csv, чтобы создать формат файла, который numpy может легко собрать в массив.

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