Скиньте масив NumPy у файл CSV


545

Чи є спосіб скинути масив NumPy у файл CSV? У мене є 2D масив NumPy і мені потрібно скинути його в читаному для людини форматі.

Відповіді:


866

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 Isaac

16
@ ÉbeIsaac Формат також можна вказати як рядок:fmt='%s'
Луїс

136

Можна використовувати 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)


4
Однак це також запише індекс стовпців у перший рядок.
RM-

5
@ RM- ви можете використовуватиdf.to_csv("file_path.csv", header=None)
maxbellec

4
Не добре. Це створює df та витрачає зайву пам’ять ні за що
Текс

20
працює як шарм, це дуже швидко - компроміс для додаткового використання пам'яті. параметри header=None, index=Noneвидалити рядок заголовка та стовпчик індексу.
thepunitsingh

3
@DaveC: Ви повинні встановити commentsаргумент ключового слова '', подання #буде придушено.
Milind R

45

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, вона зберігає все в один рядок.


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

9

Як уже обговорювалося, найкращий спосіб скинути масив у файл 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стисненому форматі, що може бути корисним під час передачі даних по мережі.

Нам просто потрібно змінити розширення файлу, оскільки .gznumpy про все подбає автоматично

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

Сподіваюся, це допомагає


1
Це fmt="%d"було те, що я шукав. Дякую!
payne

5

Я вважаю, що ви можете це зробити досить просто так:

  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

4

якщо ви хочете написати в стовпці:

    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

Ви також можете зробити це за допомогою чистого пітона без використання модулів.

# 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)

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 Будь ласка, додайте лише нові підходи, не повторюйте раніше опубліковані пропозиції.
Містер T
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.