Скиньте масив 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.