2012-03-28 3 views
7

Я хочу сохранить 2D-массив в CSV-файл с информацией о заголовке строки и столбца (например, таблицу). Я знаю, что я могу использовать аргумент заголовка для numpy.savetxt для сохранения имен столбцов, но есть ли простой способ включить другой массив (или список) в качестве первого столбца данных (например, названия строк)?Python/Numpy - Сохранить массив с заголовками столбцов и строк

Ниже приведен пример того, как я это делаю сейчас. Есть ли лучший способ включить эти названия строк, возможно, какой-то трюк с savetxt, о котором я не знаю?

import csv 
import numpy as np 

data = np.arange(12).reshape(3,4) 
# Add a '' for the first column because the row titles go there... 
cols = ['', 'col1', 'col2', 'col3', 'col4'] 
rows = ['row1', 'row2', 'row3'] 

with open('test.csv', 'wb') as f: 
    writer = csv.writer(f) 
    writer.writerow(cols) 
    for row_title, data_row in zip(rows, data): 
     writer.writerow([row_title] + data_row.tolist()) 

ответ

6

Может быть, вы бы предпочли, чтобы сделать что-то вроде этого:

# Column of row titles 
rows = np.array(['row1', 'row2', 'row3'], dtype='|S20')[:, np.newaxis] 
with open('test.csv', 'w') as f: 
    np.savetxt(f, np.hstack((rows, data)), delimiter=', ', fmt='%s') 

Это неявно преобразование data в массив строк, и занимает около 200 мс для каждого миллиона деталей в моем компьютере.

dtype '|S20' средства строки двадцать символов. Если он слишком низкий, ваши номера будут получать рубленые:

>>> np.asarray([123], dtype='|S2') 
array(['12'], 
    dtype='|S2') 

Другой вариант, что от моей ограниченные испытания медленнее, но дает вам гораздо больше контроля и не разделочной вопрос будет использовать np.char.mod, как

# Column of row titles 
rows = np.array(['row1', 'row2', 'row3'])[:, np.newaxis] 
str_data = np.char.mod("%10.6f", data) 
with open('test.csv', 'w') as f: 
    np.savetxt(f, np.hstack((rows, str_data)), delimiter=', ', fmt='%s') 
+0

Использование hstack должно воссоздать массив в памяти, хотя, правильно? Поэтому, если данные очень большие, мы должны снова переназначить эту память. Для моего конкретного приложения это вряд ли будет какой-то реальной проблемой, а просто стоит упомянуть. И, вероятно, это не так. Кажется, что savetxt должен реализовываться внутренне, даже если он должен делать решение, подобное моему (но в базовом C-коде). –

+0

Да, вы правы. Я думаю, что, возможно, все эти накладные расходы можно было бы избежать с помощью массива записей и использовать тот факт, что fmt принимает список операторов форматирования, например 'fmt = ['% s', '% f', ...]', но Я не знаком с ними, и поэтому это всего лишь предположение. – jorgeca

+0

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

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