Дамп массива NumPy в CSV-файл

545

Есть ли способ вывести массив NumPy в файл CSV? У меня есть двумерный массив NumPy, и мне нужно создать дамп в удобочитаемом формате.

правый
источник

Ответы:

867

numpy.savetxt сохраняет массив в текстовый файл.

import numpy
a = numpy.asarray([ [1,2,3], [4,5,6], [7,8,9] ])
numpy.savetxt("foo.csv", a, delimiter=",")
Джим Бриссом
источник
2
это предпочтительнее, чем цикл по массиву по размеру? Я так и думаю.
Этеш Чоудхури
51
Вы также можете изменить формат каждой фигуры с помощью ключевого слова fmt. по умолчанию это "% .18e", это может быть трудно читать, вы можете использовать "% .3e", поэтому отображаются только 3 знака после запятой.
Андреа Зонка
3
Андреа, да, я использовал% 10.5f. Это было довольно удобно.
Декстер
12
Ваш метод хорошо работает для числовых данных, но он выдает ошибку для numpy.arrayстрок. Не могли бы вы прописать метод сохранения в формате csv для numpy.arrayобъекта, содержащего строки?
Ébe Исаак
16
@ ÉbeIsaac Вы также можете указать формат в виде строки:fmt='%s'
Luis
137

Вы можете использовать pandas. Требуется дополнительная память, так что это не всегда возможно, но очень быстро и просто в использовании.

import pandas as pd 
pd.DataFrame(np_array).to_csv("path/to/file.csv")

если вы не хотите заголовок или индекс, используйте to_csv("/path/to/file.csv", header=None, index=None)

maxbellec
источник
4
Однако это также запишет индекс столбца в первой строке.
RM-
5
@ df.to_csv("file_path.csv", header=None)
RM
4
Фигово. Это создает df и потребляет дополнительную память даром
Tex
20
работает как шарм, это очень быстро - компромисс для дополнительного использования памяти. параметры header=None, index=Noneудаляют строку заголовка и столбец индекса.
thepunitsingh
3
@DaveC: Вы должны установить commentsаргумент ключевого слова в '', #будет подавлено.
Milind R
46

tofile это удобная функция для этого:

import numpy as np
a = np.asarray([ [1,2,3], [4,5,6], [7,8,9] ])
a.tofile('foo.csv',sep=',',format='%10.5f')

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

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

Запись. Эта функция не создает многострочные CSV-файлы, она сохраняет все в одну строку.

atomh33ls
источник
5
Насколько я могу судить, это не создает файл CSV, но помещает все в одну строку.
Питер
@ Питер, хорошая мысль, спасибо, я обновил ответ. Для меня это сохранить нормально в формате CSV (хотя и ограничивается одной строкой). Кроме того, ясно, что цель задающего - «сбросить его в удобочитаемом формате» - так что я думаю, что ответ уместен и полезен.
atomh33ls
6
Начиная с версии 1.5.0, np.tofile () принимает необязательный параметр newline = '\ n', чтобы разрешить многострочный вывод. docs.scipy.org/doc/numpy-1.13.0/reference/generated/…
Кевин Дж. Блэк,
2
На самом деле, np.savetext () предоставляет аргумент новой строки, а не np.tofile ()
eaydin
14

Запись массивов записей в виде CSV-файлов с заголовками требует немного больше работы.

Этот пример читает файл CSV с заголовком в первой строке, а затем записывает тот же файл.

import numpy as np

# Write an example CSV file with headers on first line
with open('example.csv', 'w') as fp:
    fp.write('''\
col1,col2,col3
1,100.1,string1
2,222.2,second string
''')

# Read it as a Numpy record array
ar = np.recfromcsv('example.csv')
print(repr(ar))
# rec.array([(1, 100.1, 'string1'), (2, 222.2, 'second string')], 
#           dtype=[('col1', '<i4'), ('col2', '<f8'), ('col3', 'S13')])

# Write as a CSV file with headers on first line
with open('out.csv', 'w') as fp:
    fp.write(','.join(ar.dtype.names) + '\n')
    np.savetxt(fp, ar, '%s', ',')

Обратите внимание, что этот пример не рассматривает строки с запятыми. Чтобы рассмотреть кавычки для нечисловых данных, используйте csvпакет:

import csv

with open('out2.csv', 'wb') as fp:
    writer = csv.writer(fp, quoting=csv.QUOTE_NONNUMERIC)
    writer.writerow(ar.dtype.names)
    writer.writerows(ar.tolist())
Майк Т
источник
Здесь снова помогают панды. Вы можете сделать: pd.DataFrame (out, columns = ['col1', 'col2']) и т. Д.
EFreak
10

Как уже говорилось, лучший способ вывести массив в файл CSV - использовать .savetxt(...)метод. Тем не менее, есть определенные вещи, которые мы должны знать, чтобы сделать это правильно.

Например, если у вас есть Numpy массив , dtype = np.int32как

   narr = np.array([[1,2],
                 [3,4],
                 [5,6]], dtype=np.int32)

и хотите сохранить, используя savetxtкак

np.savetxt('values.csv', narr, delimiter=",")

Он будет хранить данные в экспоненциальном формате с плавающей запятой как

1.000000000000000000e+00,2.000000000000000000e+00
3.000000000000000000e+00,4.000000000000000000e+00
5.000000000000000000e+00,6.000000000000000000e+00

Вам придется изменить форматирование с помощью параметра с именем , fmtкак

np.savetxt('values.csv', narr, fmt="%d", delimiter=",")

хранить данные в оригинальном формате

Сохранение данных в сжатом формате gz

Также savetxtможет использоваться для хранения данных в .gzсжатом формате, что может быть полезно при передаче данных по сети.

Нам просто нужно изменить расширение файла как .gz numpy позаботится обо всем автоматически

np.savetxt('values.gz', narr, fmt="%d", delimiter=",")

Надеюсь, поможет

Дакш
источник
1
Это fmt="%d"было то, что я искал. Спасибо!
Пейн
6

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

  1. Конвертировать массив Numpy в фрейм данных Pandas
  2. Сохранить как CSV

например, № 1:

    # Libraries to import
    import pandas as pd
    import nump as np

    #N x N numpy array (dimensions dont matter)
    corr_mat    #your numpy array
    my_df = pd.DataFrame(corr_mat)  #converting it to a pandas dataframe

например, № 2:

    #save as csv 
    my_df.to_csv('foo.csv', index=False)   # "foo" is the name you want to give
                                           # to csv file. Make sure to add ".csv"
                                           # after whatever name like in the code
DrDEE
источник
5

если вы хотите написать в столбце:

    for x in np.nditer(a.T, order='C'): 
            file.write(str(x))
            file.write("\n")

Здесь «a» - это имя массива numpy, а «file» - переменная для записи в файл.

Если вы хотите написать в строке:

    writer= csv.writer(file, delimiter=',')
    for x in np.nditer(a.T, order='C'): 
            row.append(str(x))
    writer.writerow(row)
Римхим.
источник
2

Если вы хотите сохранить массив (например your_array = np.array([[1,2],[3,4]])) в одну ячейку, вы можете сначала преобразовать его с помощьюyour_array.tolist() .

Затем сохраните его обычным способом в одну ячейку, delimiter=';' и ячейка в csv-файле будет выглядеть так[[1, 2], [2, 4]]

Тогда вы можете восстановить ваш массив следующим образом: your_array = np.array(ast.literal_eval(cell_string))

Мистер поин
источник
хорошо, что буквально собирается уничтожить всю экономию памяти при использовании массива
PirateApp
2

Вы также можете сделать это с чистым Python без использования каких-либо модулей.

# format as a block of csv text to do whatever you want
csv_rows = ["{},{}".format(i, j) for i, j in array]
csv_text = "\n".join(csv_rows)

# write it to a file
with open('file.csv', 'w') as f:
    f.write(csv_text)
Greg
источник
1
Это использует много памяти . Предпочитаю зацикливание на каждой строке и форматировать и записывать его.
Ремрам
@remram это зависит от ваших данных, но да, если он большой, он может использовать много памяти
Грег
2

В Python мы используем модуль csv.writer () для записи данных в файлы csv. Этот модуль похож на модуль csv.reader ().

import csv

person = [['SN', 'Person', 'DOB'],
['1', 'John', '18/1/1997'],
['2', 'Marie','19/2/1998'],
['3', 'Simon','20/3/1999'],
['4', 'Erik', '21/4/2000'],
['5', 'Ana', '22/5/2001']]

csv.register_dialect('myDialect',
delimiter = '|',
quoting=csv.QUOTE_NONE,
skipinitialspace=True)

with open('dob.csv', 'w') as f:
    writer = csv.writer(f, dialect='myDialect')
    for row in person:
       writer.writerow(row)

f.close()

Разделитель - это строка, используемая для разделения полей. Значением по умолчанию является запятая (,).

Тамил Сельван С
источник
Это уже было предложено: stackoverflow.com/a/41009026/8881141 Пожалуйста, добавляйте только новые подходы, не повторяйте ранее опубликованные предложения.
Мистер Т