Zrzuć tablicę NumPy do pliku csv


545

Czy istnieje sposób na zrzucenie tablicy NumPy do pliku CSV? Mam tablicę 2D NumPy i muszę ją zrzucić w formacie czytelnym dla człowieka.

Odpowiedzi:


866

numpy.savetxt zapisuje tablicę w pliku tekstowym.

import numpy
a = numpy.asarray([ [1,2,3], [4,5,6], [7,8,9] ])
numpy.savetxt("foo.csv", a, delimiter=",")

2
czy jest to lepsze niż zapętlanie tablicy przez wymiar? Tak mi się wydaje.
Ehtesh Choudhury

51
możesz również zmienić format każdej liczby za pomocą słowa kluczowego fmt. domyślnie jest to „% .18e”, może to być trudne do odczytania, możesz użyć „% .3e”, więc wyświetlane są tylko 3 miejsca po przecinku.
Andrea Zonca

3
Andrea, Tak, użyłem% 10.5f. To było całkiem wygodne.
Dexter

12
Twoja metoda działa dobrze dla danych liczbowych, ale generuje błąd dla numpy.arrayciągów. Czy możesz przepisać metodę zapisywania jako csv dla numpy.arrayobiektu zawierającego ciągi znaków?
Ébe Isaac

16
@ ÉbeIsaac Możesz również określić format jako ciąg znaków:fmt='%s'
Luis

136

Możesz użyć pandas. Zajmuje trochę dodatkowej pamięci, więc nie zawsze jest to możliwe, ale jest bardzo szybki i łatwy w użyciu.

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

jeśli nie chcesz nagłówka lub indeksu, użyj to_csv("/path/to/file.csv", header=None, index=None)


4
Spowoduje to jednak również zapisanie indeksu kolumny w pierwszym wierszu.
RM-

5
@ RM- możesz użyćdf.to_csv("file_path.csv", header=None)
maxbellec

4
Niedobrze. To tworzy plik df i zużywa dodatkową pamięć na nic
Tex

20
działał jak urok, jest bardzo szybki - kompromis za dodatkowe użycie pamięci. parametry header=None, index=Noneusuwają wiersz nagłówka i kolumnę indeksu.
thepunitsingh

3
@DaveC: Musisz ustawić commentsargument słowa kluczowego na'' , #zostanie on .
Milind R

45

tofile jest wygodną funkcją do tego celu:

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

Strona podręcznika zawiera kilka przydatnych notatek:

Jest to wygodna funkcja do szybkiego przechowywania danych macierzy. Informacje na temat endianizmu i precyzji są tracone, więc ta metoda nie jest dobrym wyborem dla plików przeznaczonych do archiwizacji danych lub transportu danych między maszynami o różnych endianiach. Niektóre z tych problemów można rozwiązać, wysyłając dane w postaci plików tekstowych, kosztem szybkości i rozmiaru pliku.

Uwaga. Ta funkcja nie tworzy wielowierszowych plików csv, zapisuje wszystko w jednej linii.


5
O ile mi wiadomo, nie tworzy to pliku csv, ale umieszcza wszystko w jednym wierszu.
Peter

@Peter, uwaga, dziękuję, zaktualizowałem odpowiedź. Dla mnie zapisuje się ok w formacie csv (choć ograniczony do jednej linii). Jest również jasne, że intencją pytającego jest „zrzucić go w formacie czytelnym dla człowieka” - więc myślę, że odpowiedź jest trafna i użyteczna.
atomh33ls

6
Od wersji 1.5.0 np.tofile () przyjmuje opcjonalny parametr newline = '\ n', aby umożliwić wyjście wieloliniowe. docs.scipy.org/doc/numpy-1.13.0/reference/generated/…
Kevin J. Black

2
W rzeczywistości np.savetext () zapewnia argument nowej linii, a nie np.tofile ()
eaydin

14

Pisanie tablic rekordów jako plików CSV z nagłówkami wymaga nieco więcej pracy.

Ten przykład czyta plik CSV z nagłówkiem w pierwszym wierszu, a następnie zapisuje ten sam plik.

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', ',')

Zauważ, że w tym przykładzie nie uwzględniono ciągów z przecinkami. Aby rozważyć oferty na dane nienumeryczne, użyj csvpakietu:

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

Tutaj znowu pomaga panda. Możesz zrobić: pd.DataFrame (out, columns = ['col1', 'col2']) itp.
EFreak

9

Jak już wspomniano, najlepszym sposobem na zrzucenie tablicy do pliku CSV jest użycie .savetxt(...) metody. Są jednak pewne rzeczy, które powinniśmy wiedzieć, aby robić to poprawnie.

Na przykład, jeśli masz tablicę numpy z dtype = np.int32as

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

i chcesz zapisać, używając savetxtjako

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

Będzie przechowywać dane w zmiennoprzecinkowym formacie wykładniczym jako

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

Będziesz musiał zmienić formatowanie za pomocą parametru o nazwie fmtas

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

do przechowywania danych w oryginalnym formacie

Zapisywanie danych w skompresowanym formacie gz

Ponadto, savetxtmogą być używane do przechowywania danych w.gz formacie skompresowanym, które mogą być przydatne podczas przesyłania danych przez sieć.

Musimy tylko zmienić rozszerzenie pliku, ponieważ .gznumpy zajmie się wszystkim automatycznie

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

Mam nadzieję, że to pomoże


1
Właśnie fmt="%d"tego szukałem. Dziękuję Ci!
payne

5

Wierzę, że możesz to osiągnąć w następujący sposób:

  1. Konwertuj tablicę Numpy na ramkę danych Pandas
  2. Zapisz jako CSV

np. # 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

np. # 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

jeśli chcesz pisać w kolumnie:

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

Tutaj „a” jest nazwą tablicy numpy, a „file” jest zmienną do zapisania w pliku.

Jeśli chcesz pisać w rzędzie:

    writer= csv.writer(file, delimiter=',')
    for x in np.nditer(a.T, order='C'): 
            row.append(str(x))
    writer.writerow(row)

2

Jeśli chcesz zapisać tablicę numpy (np. your_array = np.array([[1,2],[3,4]])) W jednej komórce, możesz ją najpierw przekonwertować your_array.tolist().

Następnie zapisz go w zwykły sposób w jednej komórce, delimiter=';' a komórka w pliku csv będzie wyglądać tak[[1, 2], [2, 4]]

Następnie możesz przywrócić tablicę w następujący sposób: your_array = np.array(ast.literal_eval(cell_string))


cóż, to dosłownie zniszczy wszystkie oszczędności pamięci przy korzystaniu z tablicy
numpy

2

Możesz to również zrobić przy użyciu czystego Pythona bez użycia żadnych modułów.

# 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
To zużywa dużo pamięci . Preferuj zapętlenie każdego wiersza, sformatuj go i napisz.
remram

@remram to zależy od twoich danych, ale tak, jeśli jest duży, może zużyć dużo pamięci
Greg

2

W Pythonie używamy modułu csv.writer () do zapisywania danych w plikach csv. Ten moduł jest podobny do modułu 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()

Separator to ciąg używany do oddzielania pól. Wartość domyślna to przecinek (,).


Zostało to już zasugerowane: stackoverflow.com/a/41009026/8881141 Dodaj tylko nowe podejścia, nie powtarzaj wcześniej opublikowanych sugestii.
Pan T
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.