Bevezetés a numpy könyvtárba#

A numpy könyvtár egy népszerű könyvtár, mely lehetővé tesz nagyméretű tömbök és mátrixok kezelését, illetve számos matematikai függvényt is tartalmaz. A könyvtár a következő módon importálható:

import numpy

A jegyzetben mindig az np aliaszt fogjuk használni:

import numpy as np

Tömbök létrehozása#

Nézzük meg hogy hozzunk létre egy tömböt:

arr = np.array([1, 2, 3, 4, 5])
print(arr)
print(type(arr))
[1 2 3 4 5]
<class 'numpy.ndarray'>

Emlékeztetőül, a lista bármilyen típusú elemt tartalmazhat. Ezzel szemben a numpy tömb csak azonos típusú elemeket tárolhat. A következőképpen tudjuk megnézni, hogy a tömb milyen típusú elemeket tárol:

arr = np.array([1, 2, 3, 4, 5])
print(arr.dtype)
int64

A példa tömb 64-bites egész típusú elemeket tartalmaz.

Kiegészítő anyag

A listával szemben, mely láncolt listaként van megvalósítva, a numpy tömb folytonos memória területet használ. Mivel az elemek azonosak, így a tömb egy elemét annak indexe alapján könnyen meg lehet határozni a memóriában: például a 10-ik elem memóriában elfolgalt helyét úgy kapjuk meg, hogy a tömb típusának méretét 10-zel felszorozzuk. Ennek az adattárolésnak vannak előnyei és hátrányai is. Hasonlítsuk össze a tömböt a listával, hogy melyik előnyösebb a következő műveletek szempontjából: elem törlése, elem beszúrása, új elem hozzáadása.

Nézzünk egy példát, amikor szöveget tárolunk:

arr = np.array(['one', 'two', 'three', 'four', 'five'])
print(arr.dtype)
<U5

Egy másik példa float értékekkel:

arr = np.array([1.2, 2.1, 3.4, 4.1, 5.1])
print(arr.dtype)
float64

Tömbök és dimenzióik#

A tömböknek van dimenziója. Így hozzunk létre egy 0 dimenziós tömböt:

arr = np.array(5)
print(arr)
5

Vegyük észre, hogy nem használtunk [] zárójeleket. Ezzel szemben az 1 dimenziós tömb:

arr = np.array([1, 2, 3, 4, 5])
print(arr)
print(type(arr))
[1 2 3 4 5]
<class 'numpy.ndarray'>

A 2 dimenziós tömbhöz két [] kapcsos zárójelet használunk:

arr = np.array([[1, 2, 3], [4, 5, 6]])
print(arr)
print(type(arr))
[[1 2 3]
 [4 5 6]]
<class 'numpy.ndarray'>

Egy több dimenzióját az ndim, míg méretét a shape attribútummal tudjuk lekérdezni a következő módon:

# 0 dimenziós tömb
a = np.array(42)
print(a.ndim)
print(a.shape)

# 1 dimenziós tömb
b = np.array([1, 2, 3, 4, 5])
print(b.ndim)
print(b.shape)

# 2 dimenziós tömb
c = np.array([[1, 2, 3], [4, 5, 6]])
print(c.ndim)
print(c.shape)
0
()
1
(5,)
2
(2, 3)

Vegyük észre, hogy a shape egy tuplet ad vissza. Így az egyes dimenziók mentén a tömb méretét a tuple indexszelésével kapjuk:

c = np.array([[1, 2, 3], [4, 5, 6]])
print('Sorok száma: ', c.shape[0])
print('Oszlopok száma: ', c.shape[1])
Sorok száma:  2
Oszlopok száma:  3

A tömbök dimenziójának számára nincs megkötés, akármekkora dimenziós tömb létezhet. Nézzünk egy példát a háromdimenziós tömbre:

a = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])
print(a)
[[[ 1  2  3]
  [ 4  5  6]]

 [[ 7  8  9]
  [10 11 12]]]

Tömbök indexszelése#

numpy tömböket a következőképpen indexszelhetjük:

# Egy dimenziós tömb indexszelése
b = np.array([1, 2, 3, 4, 5])
print(b[0])

# Két dimenziós tömb indexszelése:
c = np.array([[1, 2, 3], [4, 5, 6]])
print(c[0, 1]) 
1
2

Figyelem

Ez nagyon hasonlít a lista indexeléshez. De a tömb indexszelés különbözik egy dimenziónál nagyobb tömbök esetén, lásd:

numbers = [[1, 2, 3], [4, 5, 6]]
print(numbers[0][1]) # lista indexszelése

numpy_array = np.array(numbers) 
print(numpy_array[0, 1]) # tömb indexszelése

Iterálás tömbökön#

Iteráláshoz lekérdezhetjük a tömb méretét, és egy ciklus váltoróval az indexszet használva végig mehetünk egy egydimenziós tömbön:

b = np.array([1, 2, 3, 4, 5])
for k in range(b.shape[0]):
  print(b[k])
1
2
3
4
5

Egy sokkal tisztább kódot kapunk, ha az egydimenziós tömböt kollekióként járjuk be:

b = np.array([1, 2, 3, 4, 5])
for elem in b:
  print(elem)
1
2
3
4
5

Nézzünk egy példát kétdimenziós tömbre indexszek használatával:

numbers = np.array([[1, 2, 3], [4, 5, 6]])
for i in range(0, numbers.shape[0]):
  for j in range(0, numbers.shape[1]):
    print(numbers[i, j])
1
2
3
4
5
6

Ugyanez bejárással leegyszerűsödik az alábbiakra:

arr_2d = np.array([[1, 2, 3], [4, 5, 6]])
for row in arr_2d:
  for elem in row:
    print(elem)
1
2
3
4
5
6

Ha megnézzük, az első for ciklus row ciklus változója a tömb sorai. Ezután a tömb sorain tudunk végig iterálni.

Feladat

Írjunk kódot, amely egy kétdimenziós tömb elemeit mátrix alakban írja ki, például [[1, 2, 3], [4, 5, 6]] esetén:

1 2 3
4 5 6
7 8 9

Szeletelés (slicing) tömbökön#

A szeletelés ugyanúgy működik tömbökön, mint listán egydimenziós tömbök esetén:

arr_1d = np.array([1, 2, 3, 4, 5])

print(arr_1d[2:4])
print(arr_1d[0:4])
print(arr_1d[:4]) 

print(arr_1d[-1]) 
print(arr_1d[-3:-1]) 
print(arr_1d[-3:]) 

print(arr_1d[0:5:2]) 
print(arr_1d[0::2]) 
print(arr_1d[::2]) 
[3 4]
[1 2 3 4]
[1 2 3 4]
5
[3 4]
[3 4 5]
[1 3 5]
[1 3 5]
[1 3 5]

Kétdimenziós tömbök esetén az indexszelés logikája hasonló, az egyetlen különbség a dimenziókra való hivatkozás, ahogy azt az indexszelésnél láttuk:

arr_2d = np.array([[1, 2, 3], [4, 5, 6]])
print(arr_2d[0:2, 1:3]) 
[[2 3]
 [5 6]]

Feladat

Vegyük az alábbi tömböt: [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]. Adjunk indexszelést hogy a következő tömböt kapjuk:

  • [[2, 3], [6, 7]]

  • [[5, 6, 7, 8], [9, 10, 11, 12]]

  • [[1], [5], [9]]

  • [[4], [8], [12]]

  • [[2, 4], [6, 8], [10, 12]]

A tömbök alakját meg tudjuk változtatni. Nézzük a következő tömböt:

arr_2d = np.array([[1, 2, 3], [4, 5, 6]]) 

print(arr_2d.shape)
(2, 3)

Ez egy 2x3-as tömb. Nézzük meg mi történik, ha megváltoztatjuk a tömb méreteit. Cseréljük fel a sorhoz és oszlopk méreteit; ezt a reshape függvénnyel tudjuk megtenni:

print(arr_2d.reshape(3, 2)) 
[[1 2]
 [3 4]
 [5 6]]

Egy másik lehetőség a mátrix vektorrá alakítása:

print(arr_2d.reshape(1, 6)) 
[[1 2 3 4 5 6]]

Vegyük észre, hogy az újra méretezés során, az új méretek szorzatának meg kell egyeznie az erdeti mátrix méreteinek szorzatával. A reshape függvény esetén ha a tömb n dimenziós, akkor ha n-1 dimenzió méretét megadjuk, akkor a hiányzó dimenzió mérete egyértelmű. Ezért ilyen esetben, ha -1 értéket adunk meg a mérethez, akkor a függvény kiszámolja az utolsó dimenzió méretét:

print(arr_2d.reshape(3, -1)) 
print(arr_2d.reshape(-1, 6)) 
[[1 2]
 [3 4]
 [5 6]]
[[1 2 3 4 5 6]]

Átméretezéssel megnövelhető az eredeti tömb dimenzióját is, például:

arr_2d = np.array([[1, 2, 3], [4, 5, 6]])
arr_3d = arr_2d.reshape(2, -1, 3)

print(arr_3d.ndim)       # ez egy háromdimenziós tömb
print(arr_3d[0, 0, 1])   # ez az indexszelés a tömbben
3
2

Mély másolás tömbökön#

A numpy tömb mutable típus. Nézzünk egy példát:

a = np.array([1, 2, 3, 4, 5])
b = a

a[0] = 0

print(a)
print(b)
[0 2 3 4 5]
[0 2 3 4 5]

A copy() függvénnyel a tömb mélymásolatát tudjuk elvégezni:

a = np.array([1, 2, 3, 4, 5])
b = a.copy() # mély másolás

a[0] = 0

print(a)
print(b)
[0 2 3 4 5]
[1 2 3 4 5]

Tömbök összefűzése#

Gyakran van szükségünk arra, hogy különböző tömböket összefűzzünk, egymás alá,vagy mellé rendezzünk, és így egy új tömböt állítunsk elő. Ezekre a műveletekre nézzünk most példákat.

Nézzük a következő esetet:

arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])
con_arr = np.array([arr1, arr2])

print(con_arr)
print(con_arr.ndim)
[[1 2 3]
 [4 5 6]]
2

A fenti kódban kér egydimenziós tömböt hozzunk létre. Ezeket a tömböket ezután beletesszük egy harmadik tömbbe. Vegyük észre, hogy az így kapott tömb kétdimenziós, és az egydimenziós tömbök a kétdimenziós tömb egyes sorai.

Szükségünk lehet ugyanakkor olyan műveletre, ahol a két egydimenziós tömböt egymás után szeretnénk elrendezni, és így a keletkező tömb egydimenziós. Ezt a numpy összefűzés concatenate függvényével érthetjük el:

arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])
arr = np.concatenate((arr1, arr2))

print(arr)
print(arr.ndim)
[1 2 3 4 5 6]
1

Vegyük észre, hogy a concatenate függvényben, a tömbök egy tuplebe vannak rendezve a függvény hívásban, így a fenti kódban a concatenate egy tuple bemeneti paraméterrel van hívva. Ha egy új vátolzót hozzunk létre a tuplenek akkor a fenit kód az alábbi módon nézne ki:

arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])
arr_tuple = (arr1, arr2)
print(arr_tuple)

arr = np.concatenate((arr1, arr2))
print(arr)
(array([1, 2, 3]), array([4, 5, 6]))
[1 2 3 4 5 6]

Ez lehetőséget ad arra, hogy tetszőleges mennyiségű tömböt összefűzzünk. Az alábbi példában 4 tömböt fűzzünk össze:

arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])
arr3 = np.array([7, 8, 9])
arr4 = np.array([10, 11, 12])
arr = np.concatenate((arr1, arr2, arr3, arr4))

print(arr)
[ 1  2  3  4  5  6  7  8  9 10 11 12]

A concatenate függvény a tömb összefűzését az első dimenzió mentén hajta végre. Ezért egy két dimenziós tömb esetén a következő eredményt kapjuk:

arr_2d = np.array([[1, 2, 3], [4, 5, 6]])  # 2 x 3
print(np.concatenate((arr_2d, arr_2d)))    # 4 x 3
[[1 2 3]
 [4 5 6]
 [1 2 3]
 [4 5 6]]

Lehetőségünk van azonban más tengely mentén is elvégezni az összefűzést. Ezt a concatenate függvény axis opcionális paraméterén keresztül tudunk megadni az alábbi módon:

arr_2d = np.array([[1, 2, 3], [4, 5, 6]]) # 2 x 3
print(np.concatenate((arr_2d, arr_2d), axis=0)) # 4 x 3
print(np.concatenate((arr_2d, arr_2d), axis=1)) # 2 x 6
[[1 2 3]
 [4 5 6]
 [1 2 3]
 [4 5 6]]
[[1 2 3 1 2 3]
 [4 5 6 4 5 6]]

Vegyük észre, hogy a 0-s indexű tengely mentén össezfűzve két 2x3-as mátrxot egy 4x3-as tömböt kapunk, az 1-es indxű tengely mentén azonban egy 2x6-os tömb az eredmény.

Feladat

Az alábbi kódban karaktereket használunk helyezünk el a tömbbe. Adjuk meg mi lesz az eredménye a következő műveletknek:

  • print(np.concatenate((A, B)))

  • print(np.concatenate((A, B), axis=0))

  • print(np.concatenate((A, B), axis=1))

  • print(np.array([A, B]))

A = np.array([['*', '*', '*'], ['*', '*', '*']])
B = np.array([['#', '#', '#'], ['#', '#', '#']])

Elérhetőek továbbá vstack és hstack, mely ekvivalens a concatenate függvénnyel kétdimenziós tömbök esetén, ha

  • vstack esetén axis=0

  • hstack esetén axis=1

arr_2d = np.array([[1, 2, 3], [4, 5, 6]]) # 2 x 3
print(np.vstack((arr_2d, arr_2d)))  # 4 x 3
print(np.hstack((arr_2d, arr_2d)))  # 2 x 6
[[1 2 3]
 [4 5 6]
 [1 2 3]
 [4 5 6]]
[[1 2 3 1 2 3]
 [4 5 6 4 5 6]]

Matematikai függvények#

Ahogy a bevezetőben említettük a numpy könyvtár számos matematikai függvényt, operációt és algoritmust tartalmaz. Ezekre nézzünk most példákat.

Egyszerű matematikai függvények tömbökön:

v = np.array([0.1, 0.5, 0.8])

print(np.sin(v))
print(np.round(v))
print(np.sum(v))
print(np.diff(v))
print(np.degrees(v))
print(np.radians(v))
[0.09983342 0.47942554 0.71735609]
[0. 0. 1.]
1.4
[0.4 0.3]
[ 5.72957795 28.64788976 45.83662361]
[0.00174533 0.00872665 0.01396263]

Függvények tömbök létrehozásához#

Lehetőségünk van egydiemnziós tömböt egy sorozat elemeivel feltölteni a linspace függvény segítségével:

np.linspace(0, 20, 5)
array([ 0.,  5., 10., 15., 20.])

Ebben a függvényben az első paraméter a szakaz kezdő, a második a szakasz végpontja, a harmadik paraméter pedig azt adja meg, hogy hány egyenlő részre bontsuk fel a szakaszt. Tehát a lépésköz a szakasz hossza és a harmadik paraméter alapján kerül meghatározásra. Ez a fajta megadási módja egy sorozatnak gyakran célszerű, mivel megadható, hogy hány elemű legyen a sorozat. Azonban bizonyos feladatok esetén célszerű lehet, hogy a lépésközt adjuk meg, melyet az arange függvény tehetünk meg:

np.arange(0, 20, 5)
array([ 0,  5, 10, 15])

Az arange esetén is a szakasz kezdő és végpontja az első és második paraméter, a harmadik pedig a lépésköz. arange esetén lehetőségünk van nem egész lépésköz megadására.

np.arange(0, 20, 5.2)
array([ 0. ,  5.2, 10.4, 15.6])

Továbbá, mivel ezek tömbök ezért ez a sorozat bejárható for ciklussal:

for n in np.arange(0, 20, 5.2):
    print(n)
0.0
5.2
10.4
15.600000000000001

Figyelem

Tanultunk hasonló sorozat generálást a range segítségével, azonban ott nem tudtunk megadni tört lépésközt. A következő kód például hibával leáll:

range(0, 20, 0.5) # TypeError: 'float' object cannot be interpreted as an integer

Más függvények segítséget nyújtanak speciális típusú mátrxszot tartalmazó tömb létrehozására. Kétdimenziós tömb létrehozása, mely egységmátrxot reprezentál:

np.eye(3)
array([[1., 0., 0.],
       [0., 1., 0.],
       [0., 0., 1.]])

Ha az eye függvénynek két bemenetet adunk, akkor megadhatjuk az eredmény tömb sorainak és oszlopainak számát:

np.eye(2,3)
array([[1., 0., 0.],
       [0., 1., 0.]])

Ekkor láthatjuk, hogy az 1-esek a dimenziónak megfelelően lesznek elhelyezve.

Ugyanígy nullákkal is létrehozható a tömb:

np.zeros(3)
array([0., 0., 0.])

Valamint:

np.zeros((3,3))
array([[0., 0., 0.],
       [0., 0., 0.],
       [0., 0., 0.]])

Figyelem

Figyljünk oda, hogy eye függvény hívásakor, ha egy számot adunk meg, akkor egy négyzetes tömböt kapunk. Ez a zero függvény esetén fordítva van. Továbba, ha a tömbnek meg akarjuk adni a méretét, akkor az eye esetén két bemeneti paraméterrel tudjuk ezt megtenni; a zero esetén azonban tuplet kell használnunk.

Mátrix műveletek tömbökön#

Tömbökket egyszerűen tudunk transzponálni. Példa egy vektort reprezentáló tömbön:

v = np.array([[1, 2, 3]])
vt = v.T

print(v.shape)
print(vt.shape)
(1, 3)
(3, 1)

És egy mátrixot reprezentáló tömbön:

M = np.array([[1, 2, 3], [4, 5, 6]])

print(M)
print(M.T)
[[1 2 3]
 [4 5 6]]
[[1 4]
 [2 5]
 [3 6]]

Tömbökön elvégezhetünk skalárral való műveleteket és tömbök közötti összeadás és kivonás műveleteket, ahogy lineáris algebrában ismert:

v1 = np.array([1, 2, 3])
v2 = np.array([1, 2, 3])

print(1 - v1)
print(2*v1)
print(v1 + v2)
print(v1 - v2)
[ 0 -1 -2]
[2 4 6]
[2 4 6]
[0 0 0]

Ezután nézzük meg mi történik szorzáskor:

v1 = np.array([1, 2, 3])
v2 = np.array([1, 2, 3])
r = v1 * v2

print(r)
[1 4 9]

Vegyük észre, hogy a fenti szorzás elemenként kerül végrehatásra, ami nem megszokott lineáris algebrából. Amennyiben vektor vagy mátrix szorzást szeretnénk végrehajtani a @ jelet kell alkalmaznunk:

v1 = np.array([1, 2, 3])
v2 = np.array([1, 2, 3])
r = v1 @ v2

print(r)
14

A fenti kód két sor-vektor szorzását jelentené, így mátrix artimetikát használva a művelet nem elvégezhető. Azonban a bal és jobb oldali operandus egydimenziós vektor, ezért a @ művelet automatikus skaláris szorzatként lesz értelmezve. Valójában pontosabb azt mondanunk, hogy v1 és v2 vektorok, melyek se nem sor vagy oszlop vektorok, hanem csak azt tudjuk, hogy vektorok. A szorzáskor pedig skaláris szorzást végzünk, mely két vektor között értelmezhető.

A vektorokat kétdimenziós tömbként is tudjuk definiálni. Ekkor szükséges a mátrix artimetika figyelembe vétele, és a jobb operandus transzponálása:

v1 = np.array([[1, 2, 3]])
v2 = np.array([[1, 2, 3]])

#r = v1 @ v2 # Hiba: ValueError: matmul: Input operand 1 has a mismatch
r = v1 @ v2.T

print(r)
print(r.shape)
[[14]]
(1, 1)

Vegyük észre, hogy az eredmény egy kétdimenziós 1x1-es tömb.

Kiegészítő anyag

Eddig tudatosan kerültük hogy a tömböket összekeverjük mátrixszokkal. Ennek egyik oka a fenti példa, vagyis hogy a szorzás nem a hagyományos mátrix műveletként van értelmezve tömbökön. numpyban elérhető egy matrix típus, mely nagyon hasonló a tömbhöz, de fontos különbség, hogy a mátrix csak kétdimenziós lehet. Mivel régóta a tömbökön is elérhető minden olyan művelet mely mátrixokon, és mivel a tömbök a mátrixok általánosításának tekinthetőek, ezért a továbbiakban tömböket fogunk hsználni, és a tömb és mátrix szavakat szinonímaként fogjuk használni. Az alábbi kódrészlet mutat példát a mátrix típus használatára, ahol a hagyományos * művelet mátrix szorzásként van értelmezve:

v1 = np.matrix([1, 2, 3])
v2 = np.matrix([1, 2, 3])

print(v1 * v2.T)

Bár megadható hagyományos mátrix műveletekkel is, Lehetőség van függvények használatára a skaláris (dot) és vektoriális (cross) szorzat előállítására:

v1 = np.array([1, 2, 3])
v2 = np.array([1, 2, 3])

vdot = np.dot(v1, v2)
vcross = np.cross(v1, v2)

print(vdot)
print(vcross)
14
[0 0 0]

Mátrix-vektor szorzás is elvégezhető az alábbi módon:

v = np.array([1, 2, 3])
M = np.eye(3)
r = M @ v

print(r)
[1. 2. 3.]

Vegyük észre, hogy az eredmény vektor egy sor vektor, ami ellentétes azzal, amit lineáris algebrából várnánk. Ennek oka, hogy a v vektor egydimenziós volt. Gyakran ezzel nincs semmi problémánk, és további műveletek a megszokott módon elvégezhetőek. Ha azonban szükséges az eredmény vektor alakja, akkor szükséges, hogy a bemeneti vektor kétdimenziós legyen:

v = np.array([[1, 2, 3]])
M = np.eye(3)
r = M @ v.T

print(r)
[[1.]
 [2.]
 [3.]]

Másik lehetőség, a reshape használatával dimenzió beillesztése:

v = np.array([1, 2, 3])
M = np.eye(3)
r = M @ v
r = r.reshape(-1, 1)

print(r)
[[1.]
 [2.]
 [3.]]

Összefoglalva a @ művelet tömbökön a következő eredményeket adhatja a bal és jobb oldali operandus dimenziója szerint:

  • 1d @ 1d -> number

  • 2d @ 1d -> 1d

  • 2d @ 2d -> 2d

Numerikus adatok olvasása/írása szöveges fájból#

numpy könyvtár segítéségével egyszerűen tudunk beolvasni mátrix jellegű táblázatot tartalmazó szöveges fájlokat (például CSV fájl) a loadtxt függvény segítségével:

data = np.loadtxt('./data/path.txt')

print(type(data))   # az eredmény egy tömb
print(data.dtype)   # a tömb elemeinek a típusa
print(data[:5, :])  # néhány elem
<class 'numpy.ndarray'>
float64
[[645779.76 272117.78]
 [645864.1  272075.3 ]
 [645910.56 272052.37]
 [645942.09 272030.22]
 [645982.8  271968.36]]

Figyelem

Az adat fájlok elérhetőek a tantárgy honlapján!

Figyelem

Mivel ez a függvény az adatokat egy tömbbe tölti be, ezért fontos, hogy a fájl táblázata ugyanolyan típusú adatokat kell tartalmaznia. A loadtxt függvény nem alkalmas arra, hogyha számokat tartalmazó oszlopok mellett van olyan oszlop, amely szöveget is tartalmaz. Szöveg csak a fejlécben szerepelhet, és ennek kezelésének módját az alábbiakban részletezzük.

Az adatok szöveges fájlba mentése is egyszerű:

np.savetxt('output/path.txt', data)

Kiírásakor a számok formátuma megadható, így a számok jobban értelmezhetőek. Ehhez az fmt opcionális parametért kell megadni. A formázási opciókról a specifikáció ad további információt. A következő példában a számokat két tizedesjegyig írjuk ki:

np.savetxt('output/path_semicolon.txt', data, fmt='%.2f')

Alapértelmezetten a szöveges fájlban a , szolgál a soron belüli elemek elválasztására. Magyar beállítás mellett, Excel ; használ CSV exportálás során. A loadtxt és savetxt lehetőséget ad az elválasztó jel megadására a delimiter opcionális paraméteren keresztül:

np.savetxt('output/path_semicolon.txt', data, delimiter=';')
data = np.loadtxt('output/path_semicolon.txt', delimiter=';')

A fájlhoz fejlécet a header parametér segítségével adhatunk. Alapértelmezetten numpy hozzáfűzne egy # karaktert a fejléc sor elejére, ami problémát okozhat, ha a fájlt Excelben nyitjuk meg. Ezt elkerülendő a comments paramétert üres szövegre kell állítani:

np.savetxt('output/path_header.txt', data, fmt='%.2f', delimiter=';', header='x [m];y [m]', comments='')

Amennyiben a fájlunk fejlécet tartalmaz, akkor problémánk lehet a fájl beolvasásakor, mivel a fejléc szöveget tartalmaz. Ezt elkerülendő, megadható, hogy hány sort hagyjon ki a loadtxt függvény a skiprows paraméteren keresztül. Az alábbi kódban az első sort nem veszük figyelembe, mely jól működik ha a fejlécünk az első sor a fájlban:

data_no_header = np.loadtxt('output/path_header.txt', delimiter=';', skiprows=1)

Kiegészítő anyag

Ha a fájl, amit beakarunk olvasni nem táblázatos jellegű vagy szöveget is tartalmazz, akkor a fájl olvasást hagyományos úton kell megoldani. Az alábbi weboldalon találhatunk további információkat erről.