Подтвердить что ты не робот

Как использовать numpy.genfromtxt, когда первый столбец является строкой, а остальные столбцы - номерами?

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

data = numpy.genfromtxt('data.txt', delimiter = ',')

Это хорошо читает большинство данных, но столбец ярлыков просто получает "nan". Как я могу справиться с этим?

4b9b3361

Ответ 1

По умолчанию np.genfromtxt использует dtype=float: почему строковые столбцы преобразуются в NaN, потому что, в конце концов, они не являются числом...

Вы можете попросить np.genfromtxt попытаться угадать фактический тип столбцов с помощью dtype=None:

>>> from StringIO import StringIO
>>> test = "a,1,2\nb,3,4"
>>> a = np.genfromtxt(StringIO(test), delimiter=",", dtype=None)
>>> print a
array([('a',1,2),('b',3,4)], dtype=[('f0', '|S1'),('f1', '<i8'),('f2', '<i8')])

Вы можете получить доступ к столбцам, используя их имя, например a['f0']...

Использование dtype=None - хороший трюк, если вы не знаете, какими должны быть ваши столбцы. Если вы уже знаете, какой тип они должны иметь, вы можете указать явный dtype. Например, в нашем тесте мы знаем, что первый столбец является строкой, второй - int, и мы хотим, чтобы третий был float. Тогда мы использовали бы

>>> np.genfromtxt(StringIO(test), delimiter=",", dtype=("|S10", int, float))
array([('a', 1, 2.0), ('b', 3, 4.0)], 
      dtype=[('f0', '|S10'), ('f1', '<i8'), ('f2', '<f8')])

Использование явного dtype гораздо эффективнее, чем использование dtype=None и является рекомендуемым способом.

В обоих случаях (dtype=None или явный, неоднородный dtype) вы получаете структурированный массив.

[Примечание: при dtype=None вход обрабатывается второй раз, а тип каждого столбца обновляется, чтобы соответствовать большему типу: сначала мы пытаемся использовать bool, затем int, затем float, затем сложный, тогда мы сохраняем строку, если все остальное терпит неудачу. На самом деле реализация довольно сложная. Были некоторые попытки сделать угадывание типа более эффективным (с использованием regexp), но ничего не застряло до сих пор]

Ответ 2

Если ваш файл данных структурирован таким образом

col1, col2, col3
   1,    2,    3
  10,   20,   30
 100,  200,  300

то numpy.genfromtxt может интерпретировать первую строку как заголовки столбцов, используя опцию names=True. Благодаря этому вы можете получить доступ к данным очень удобно, указав заголовок столбца:

data = np.genfromtxt('data.txt', delimiter=',', names=True)
print data['col1']    # array([   1.,   10.,  100.])
print data['col2']    # array([   2.,   20.,  200.])
print data['col3']    # array([   3.,   30.,  300.])

Так как в вашем случае данные формируются следующим образом

row1,   1,  10, 100
row2,   2,  20, 200
row3,   3,  30, 300

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

labels = np.genfromtxt('data.txt', delimiter=',', usecols=0, dtype=str)
raw_data = np.genfromtxt('data.txt', delimiter=',')[:,1:]
data = {label: row for label, row in zip(labels, raw_data)}

Первая строка считывает первый столбец (метки) в массив строк. Вторая строка считывает все данные из файла, но отбрасывает первый столбец. Третья строка использует понимание словаря для создания словаря, который можно использовать очень похоже на структурированный массив, который numpy.genfromtxt создает с помощью опции names=True:

print data['row1']    # array([   1.,   10.,  100.])
print data['row2']    # array([   2.,   20.,  200.])
print data['row3']    # array([   3.,   30.,  300.])

Ответ 3

data=np.genfromtxt(csv_file, delimiter=',', dtype='unicode')

Это отлично работает для меня.

Ответ 4

Вы можете использовать numpy.recfromcsv(filename): типы каждого столбца будут автоматически определены (как если бы вы использовали np.genfromtxt() с dtype=None) и по умолчанию delimiter=",". Это в основном ярлык для np.genfromtxt(filename, delimiter=",", dtype=None), на который указал Пьер ГМ в своем ответе.

Ответ 5

Для набора данных этого формата:

CONFIG000   1080.65 1080.87 1068.76 1083.52 1084.96 1080.31 1081.75 1079.98
CONFIG001   414.6   421.76  418.93  415.53  415.23  416.12  420.54  415.42
CONFIG010   1091.43 1079.2  1086.61 1086.58 1091.14 1080.58 1076.64 1083.67
CONFIG011   391.31  392.96  391.24  392.21  391.94  392.18  391.96  391.66
CONFIG100   1067.08 1062.1  1061.02 1068.24 1066.74 1052.38 1062.31 1064.28
CONFIG101   371.63  378.36  370.36  371.74  370.67  376.24  378.15  371.56
CONFIG110   1060.88 1072.13 1076.01 1069.52 1069.04 1068.72 1064.79 1066.66
CONFIG111   350.08  350.69  352.1   350.19  352.28  353.46  351.83  350.94

Этот код работает для моего приложения:

def ShowData(data, names):
    i = 0
    while i < data.shape[0]:
        print(names[i] + ": ")
        j = 0
        while j < data.shape[1]:
            print(data[i][j])
            j += 1
        print("")
        i += 1

def Main():
    print("The sample data is: ")
    fname = 'ANOVA.csv'
    csv = numpy.genfromtxt(fname, dtype=str, delimiter=",")
    num_rows = csv.shape[0]
    num_cols = csv.shape[1]
    names = csv[:,0]
    data = numpy.genfromtxt(fname, usecols = range(1,num_cols), delimiter=",")
    print(names)
    print(str(num_rows) + "x" + str(num_cols))
    print(data)
    ShowData(data, names)

Выход Python-2:

The sample data is:
['CONFIG000' 'CONFIG001' 'CONFIG010' 'CONFIG011' 'CONFIG100' 'CONFIG101'
 'CONFIG110' 'CONFIG111']
8x9
[[ 1080.65  1080.87  1068.76  1083.52  1084.96  1080.31  1081.75  1079.98]
 [  414.6    421.76   418.93   415.53   415.23   416.12   420.54   415.42]
 [ 1091.43  1079.2   1086.61  1086.58  1091.14  1080.58  1076.64  1083.67]
 [  391.31   392.96   391.24   392.21   391.94   392.18   391.96   391.66]
 [ 1067.08  1062.1   1061.02  1068.24  1066.74  1052.38  1062.31  1064.28]
 [  371.63   378.36   370.36   371.74   370.67   376.24   378.15   371.56]
 [ 1060.88  1072.13  1076.01  1069.52  1069.04  1068.72  1064.79  1066.66]
 [  350.08   350.69   352.1    350.19   352.28   353.46   351.83   350.94]]
CONFIG000:
1080.65
1080.87
1068.76
1083.52
1084.96
1080.31
1081.75
1079.98

CONFIG001:
414.6
421.76
418.93
415.53
415.23
416.12
420.54
415.42

CONFIG010:
1091.43
1079.2
1086.61
1086.58
1091.14
1080.58
1076.64
1083.67

CONFIG011:
391.31
392.96
391.24
392.21
391.94
392.18
391.96
391.66

CONFIG100:
1067.08
1062.1
1061.02
1068.24
1066.74
1052.38
1062.31
1064.28

CONFIG101:
371.63
378.36
370.36
371.74
370.67
376.24
378.15
371.56

CONFIG110:
1060.88
1072.13
1076.01
1069.52
1069.04
1068.72
1064.79
1066.66

CONFIG111:
350.08
350.69
352.1
350.19
352.28
353.46
351.83
350.94