2016-07-28 3 views
3

Я несколько раз сталкивался с этой проблемой и пробовал несколько разных подходов, но я не могу понять, что это правильно. Это упрощенная версия моего файла данных в формате CSV: testme.csvПопытка извлечь часть csv в массив numpy

"Name", "City", "State", "1996-04", "1996-05", "1996-06", "1996-07" 
    "Bob", "Portland", "OR", 100000, 120000, 140000, 160000 
    "Sally", "Eugene", "OR", 50000, 75000, 80000, 90000 
    "Peter", "San Francisco", "CA", , , 440000, 500000 

Я хочу, чтобы извлечь числа как 2D массив, которые я хочу сделать некоторую математику на. Однако перед этим я должен игнорировать эти текстовые поля. Кроме того, некоторые строки не будут иметь номера для всех столбцов, но как только числа начинаются, они непрерывны вправо (т. Е. Некоторые строки имеют пустые элементы для первых нескольких столбцов), и это может быть разным для каждой строки. Кроме того, множество реальных данных имеет сотни строк и столбцов десятки

Это часть того, что я пробовал:

import csv 
    import numpy as np 

    filename = "testme.csv" 

    ifile = open(filename, 'r') 
    header1 = ifile.readline() 

    reader = csv.reader(ifile) 
    A = np.array([]).reshape(0, 4) 

    for row in reader: 
     print row 
     print row[3:] 
     A = np.vstack([A, row[3:]]) 

    print A 

А потом я получаю это:

['Bob', ' "Portland"', ' "OR"', ' 100000', ' 120000', ' 140000', ' 160000'] 
    [' 100000', ' 120000', ' 140000', ' 160000'] 
    ['Sally', ' "Eugene"', ' "OR"', ' 50000', ' 75000', ' 80000', ' 90000'] 
    [' 50000', ' 75000', ' 80000', ' 90000'] 
    ['Peter', ' "San Francisco"', ' "CA"', ' ', ' ', ' 440000', ' 500000'] 
    [' ', ' ', ' 440000', ' 500000'] 
    [[' 100000' ' 120000' ' 140000' ' 160000'] 
    [' 50000' ' 75000' ' 80000' ' 90000'] 
    [' ' ' ' ' 440000' ' 500000']] 

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

Благодарим вас за консультацию и помощь заблаговременно!

Аарон

Update (8/1/16) я пойти с методом genfromtxt как соответствует то, что мне нужно было много. Вот результат для потомства и другие

import csv 
    import numpy as np 

    NumIgnoreFirstCols = 3 
    filename = "testme2.csv" 

    ifile = open(filename, 'r') 
    reader = csv.reader(ifile) 
    header1 = next(reader) 
    numcols = len(header1) 
    #Find number of cols for usecol in genfromtxt 
    print("numcols", numcols) 
    ifile.close() 

    print(range(NumIgnoreFirstCols, numcols)) 

    aMatrix = np.genfromtxt(filename, skip_header=1, delimiter=',', usecols=range(NumIgnoreFirstCols,numcols), dtype=int) 

    print aMatrix 

    normalizedMatrix = np.where(aMatrix<0, 0, aMatrix) 
    print(normalizedMatrix) 

    minValue = np.amin(normalizedMatrix) 
    maxValue = np.amax(normalizedMatrix) 
    print (minValue, maxValue) 
снова

Спасибо за помощь

ответ

2

С вашего образца, numpygenfromtxt работы:

In [166]: np.genfromtxt('stack38627130.csv',names=True,delimiter=',',dtype=None) 

Out[166]: 
array([(b'"Bob"', b' "Portland"', b' "OR"', 100000, 120000, 140000, 160000), 
     (b'"Sally"', b' "Eugene"', b' "OR"', 50000, 75000, 80000, 90000), 
     (b'"Peter"', b' "San Francisco"', b' "CA"', -1, -1, 440000, 500000)], 
     dtype=[('Name', 'S7'), ('City', 'S16'), ('State', 'S5'), ('199604', '<i4'), ('199605', '<i4'), ('199606', '<i4'), ('199607', '<i4')]) 

Это является 1d структурированный массив; доступ столбцов по имени поля (здесь, полученное из вашей строки заголовка)

In [167]: data=_ 
In [168]: data['199604'] 
Out[168]: array([100000, 50000,  -1]) 
In [169]: data['199607'] 
Out[169]: array([160000, 90000, 500000]) 

Отсутствующие поля заполнены -1. Я думаю, что это можно изменить.

Существуют и другие параметры для установки имен полей, если вам не нравятся выведенные.

Чтение может быть ограничено числовыми столбцами; различное заполнение в зависимости от dtype.

In [171]: np.genfromtxt('stack38627130.csv',skip_header=1,delimiter=',',usecols= 
    ...: [3,4,5,6]) 
Out[171]: 
array([[ 100000., 120000., 140000., 160000.], 
     [ 50000., 75000., 80000., 90000.], 
     [  nan,  nan, 440000., 500000.]]) 
In [172]: np.genfromtxt('stack38627130.csv',skip_header=1,delimiter=',',usecols= 
    ...: [3,4,5,6],dtype=int) 
Out[172]: 
array([[100000, 120000, 140000, 160000], 
     [ 50000, 75000, 80000, 90000], 
     [ -1,  -1, 440000, 500000]]) 

Теперь мы получаем 2-мерный массив.

Я считаю, что pandas обрабатывает недостающие поля лучше, но до тех пор, пока эти поля отмечены разделителем, genfromtxt не должно иметь проблем.

genfromtxt примерно делает:

result = [] 
for row in reader: 
    data = row[3:] 
    data = [float(x) for x in data] 
    result.append(data) 
result = np.array(result) 

np.array может сделать преобразование с плавающей точкой, если все строки преобразовать должным образом; он не обрабатывает пустые или nan. Обычно собирать список значений лучше, чем повторять vstack (или объединяет).

+0

Я пошел с этим решением, поскольку он соответствовал большей части того, что мне нужно. Я отправлю то, что я использовал, наконец, –

1

Если - и это большое если (я обманываю) - вы можете использовать pandas:

from StringIO import StringIO 
s = StringIO(''' "Name", "City", "State", "1996-04", "1996-05", "1996-06", "1996-07" 
        "Bob", "Portland", "OR", 100000, 120000, 140000, 160000 
        "Peter", "San Francisco", "CA", , , 440000, 500000 ''') 
df = pd.read_csv(s,skipinitialspace=True) 

Как добраться ...

 
>>> df 
    Name   City State 1996-04 1996-05 1996-06 1996-07 
0 Bob  Portland OR 100000.0 120000.0 140000 160000 
1 Peter San Francisco CA  NaN  NaN 440000 500000 

зажима к нулю, как вы говорите:

df = df.fillna(0) 

Я думаю, что это конечный результат вы хотите:

 
>>> df 
    Name   City State 1996-04 1996-05 1996-06 1996-07 
0 Bob  Portland OR 100000.0 120000.0 140000 160000 
1 Peter San Francisco CA  0.0  0.0 440000 500000 
+0

Правильный инструмент для правильной работы. Numpy отлично, но он не обрабатывает разнородные (разные) типы данных. – Mephy

+1

'numpy' может обрабатывать разнородные типы данных - со структурированными массивами. Люди используют 'genfromtxt' для этого все время. Много вопросов об этом. – hpaulj

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