NumPy 2.x: Guide till nya funktioner, prestanda och migration (2.0–2.4)

Allt du behöver veta om NumPy 2.x-serien: brytande API-ändringar, nya funktioner som matvec och StringDType, OpenMP-stöd, same_value casting och en steg-för-steg migrationsstrategi med Ruff.

Introduktion: En ny era för NumPy

NumPy 2.0 släpptes i juni 2024, och det var — utan överdrift — den största uppdateringen sedan 2006. Elva månaders intensivt arbete av 212 utvecklare resulterade i en version som förändrade spelplanen rejält. Sedan dess har det rullat på med 2.1, 2.2, 2.3 och senast 2.4 (december 2025). Sammantaget är det den mest genomgripande moderniseringen av Pythons numeriska grundbibliotek vi någonsin sett.

I den här guiden går vi igenom alla viktiga förändringar i NumPy 2.x-serien: från de brytande API-ändringarna i 2.0, via prestandaförbättringar och nya funktioner i 2.2–2.3, till den senaste 2.4-versionen med utökat stöd för användardefinerade datatyper och trådfri Python. Vi tar med praktiska kodexempel, migrationstips och bästa praxis så du kan komma igång direkt.

NumPy 2.0: De stora förändringarna

Uppsnyggning av Python API:et

En av de mest märkbara förändringarna i NumPy 2.0 är den rejäla städningen av namnrymden. Ungefär 100 medlemmar av np-namnrymden har tagits bort, flyttats eller markerats som föråldrade. Om du har jobbat med NumPy ett tag vet du att det kunde vara lite rörigt — nu är det betydligt renare.

# Funktioner som tagits bort eller flyttats i NumPy 2.0
# Gammal kod (fungerar inte i 2.0):
import numpy as np

# np.bool — borttagen, använd np.bool_ istället
# np.int — borttagen, använd np.int_ eller int istället
# np.float — borttagen, använd np.float64 istället
# np.complex — borttagen, använd np.complex128 istället
# np.object — borttagen, använd np.object_ istället
# np.str — borttagen, använd np.str_ istället

# Ny korrekt kod i NumPy 2.0:
x = np.array([1.0, 2.0, 3.0], dtype=np.float64)
y = np.array([True, False], dtype=np.bool_)
z = np.array([1, 2, 3], dtype=np.int64)

Huvudnamnrymden krympte med cirka 10 procent, och numpy.lib reducerades med hela 80 procent. Ärligt talat, det var på tiden.

Nya regler för typpromotion (NEP 50)

Det här är en förändring som kan bita dig om du inte är förberedd. NumPy 2.0 introducerar helt nya regler för hur skalära värden och arrayer kombineras vid beräkningar. Tidigare kunde resultatet av en operation bero på de faktiska värdena i en array — inte bara deras datatyper. Det ledde till konstiga överraskningar.

import numpy as np

# I NumPy 1.x kunde detta ge olika resultat beroende på värde:
# np.array([1], dtype=np.int8) + 127 -> int8
# np.array([1], dtype=np.int8) + 128 -> int16 (oväntat!)

# I NumPy 2.0 bestäms typen enbart av dtype:
a = np.array([1], dtype=np.int8)
resultat = a + 127  # Alltid int8 i 2.0
print(resultat.dtype)  # int8

# Python-skalärer "anpassar sig" till arrayens dtype:
b = np.array([1.0], dtype=np.float32)
c = b + 1.5  # float32, inte float64
print(c.dtype)  # float32

Typhanteringen blir alltså mycket mer förutsägbar. Men om du förlitade dig på det gamla beteendet behöver du granska din kod noga.

Ändrad standardtyp för heltal

På 64-bitarssystem är standardheltalstypen nu int64 istället för den plattformsberoende C-typen long. En subtil men viktig förändring, särskilt för kod som pratar med kompilerade bibliotek:

import numpy as np

# Standardheltal är nu alltid int64 på 64-bitarssystem
arr = np.array([1, 2, 3])
print(arr.dtype)  # int64

# Om du behöver C long-kompatibilitet:
arr_long = arr.astype("long", copy=False)
print(arr_long.dtype)  # plattformsberoende

Det nya DType API:et (NEP 42)

Okej, det här är kanske den mest spännande nyheten under huven. Det offentliga DType API:et (baserat på NEP 42) gör det möjligt att skapa helt anpassade datatyper utanför NumPy, med fullt stöd för casting, ufuncs och alla andra NumPy-operationer.

import numpy as np

# StringDType — den nya variabellängds-strängtypen (NEP 55)
from numpy.dtypes import StringDType

# Skapa en array med variabellängdssträngar
texter = np.array(["hej", "världen", "NumPy 2.0"], dtype=StringDType())
print(texter)
# ['hej' 'världen' 'NumPy 2.0']
print(texter.dtype)
# StringDType()

ABI-brott och C API-förändringar

NumPy 2.0 bryter det binära gränssnittet (ABI). I klartext: alla C-tillägg kompilerade mot NumPy 1.x måste kompileras om. Strukturen PyArray_Descr är nu mer ogenomskinlig för att möjliggöra framtida förbättringar. Underhåller du paket med C-tillägg som beror på NumPy? Då är omkompilering ett måste.

Automatiserad migration med Ruff

Så, låt oss prata om hur du faktiskt migrerar. Det bästa verktyget för jobbet är Ruff-lintern med regeln NPY201. Den kan automatiskt hitta och fixa många av de föråldrade API-anropen åt dig:

# Installera Ruff
pip install "ruff>=0.4.8"

# Kontrollera din kodbas
ruff check --preview --select NPY201 min_kod.py

# Automatisk korrigering
ruff check --preview --fix --select NPY201 min_kod.py

Konfigurera Ruff i din pyproject.toml:

# pyproject.toml
[tool.ruff]
preview = true

[tool.ruff.lint]
select = ["NPY201"]

Ruff fixar de flesta namnbyten, borttagna funktioner och API-förändringar automatiskt. Min rekommendation: kör det som absolut första steg i migreringsprocessen. Det sparar en hel del manuellt jobb.

NumPy 2.2: Nya matrisfunktioner och förbättringar

matvec och vecmat

NumPy 2.2 (december 2024) kom med två efterlängtade funktioner: np.matvec och np.vecmat. De kompletterar np.matmul och np.vecdot (som lades till i 2.0) på ett naturligt sätt.

import numpy as np

# matvec — matris-vektorprodukt
matris = np.array([[1, 2], [3, 4]])
vektor = np.array([5, 6])

resultat = np.matvec(matris, vektor)
print(resultat)  # [17 39]

# vecmat — vektor-matrisprodukt
resultat2 = np.vecmat(vektor, matris)
print(resultat2)  # [23 34]

# Fungerar med stackar (batchar) av matriser
batch_matriser = np.random.randn(10, 3, 3)
batch_vektorer = np.random.randn(10, 3)
batch_resultat = np.matvec(batch_matriser, batch_vektorer)
print(batch_resultat.shape)  # (10, 3)

Äntligen slipper man den omständliga v[:, :, np.newaxis]-dansen för matris-vektorprodukter.

Förbättrad array-representation

En liten men trevlig förbättring: stora arrayer som sammanfattas med ... visar nu alltid sin form. Otroligt smidigt vid felsökning.

import numpy as np

stor_array = np.zeros((1000, 500))
print(repr(stor_array))
# array([[0., 0., 0., ..., 0., 0., 0.],
#        [0., 0., 0., ..., 0., 0., 0.],
#        [0., 0., 0., ..., 0., 0., 0.],
#        ...,
#        [0., 0., 0., ..., 0., 0., 0.],
#        [0., 0., 0., ..., 0., 0., 0.],
#        [0., 0., 0., ..., 0., 0., 0.]], shape=(1000, 500))

Beteendeförändring för tomma arrayer

Viktigt att veta: bool(np.array([])) ger nu ett fel i NumPy 2.2. Tidigare returnerade det False, men det beteendet ansågs (med rätta, tycker jag) vara förvirrande:

import numpy as np

tom_array = np.array([])

# Nytt beteende i NumPy 2.2 — detta ger ValueError:
# if tom_array:  # ValueError!
#     print("Inte tom")

# Korrekt sätt att kontrollera om en array är tom:
if tom_array.size > 0:
    print("Arrayen har element")
else:
    print("Arrayen är tom")

Förbättrade typannoteringar

numpy.float64 och numpy.complex128 markeras nu korrekt som subtyper av Pythons inbyggda float respektive complex. Det kanske låter som en liten sak, men om du använder mypy eller pyright så märker du skillnaden direkt:

import numpy as np

# Tidigare gav detta ett typfel i mypy/pyright:
x: float = np.float64(3.14)  # Nu OK!
z: complex = np.complex128(1 + 2j)  # Nu OK!

# Det gör det mycket smidigare att blanda NumPy-typer
# med vanlig Python-kod

NumPy 2.3: OpenMP-stöd och prestandaoptimering

Parallell sortering med OpenMP

NumPy 2.3 (juni 2025) tog med sig något riktigt intressant: OpenMP-parallellisering. När NumPy byggs med flaggan -Denable_openmp=true kan np.sort och np.argsort utnyttja flera trådar. För stora arrayer kan det göra märkbar skillnad.

import numpy as np
import time

# Skapa en stor array att sortera
data = np.random.randn(10_000_000)

# Sortering drar nu nytta av OpenMP (om aktiverat vid bygget)
start = time.perf_counter()
sorterad = np.sort(data)
slut = time.perf_counter()
print(f"Sortering: {slut - start:.3f} sekunder")

# argsort fungerar på samma sätt
start = time.perf_counter()
index = np.argsort(data)
slut = time.perf_counter()
print(f"Argsort: {slut - start:.3f} sekunder")

Kopieringsfri pickling

Ytterligare en prestandavinst: NumPy 2.3 stödjer kopieringsfri (no-copy) pickling för arrayer som kan transponeras till C-sammanhängande format. Det minskar minnesanvändningen rejält vid serialisering av stora arrayer.

import numpy as np
import pickle

# Stor array
stor_data = np.random.randn(1000, 1000)

# Pickling är nu effektivare — ingen extra kopia behövs
serialiserad = pickle.dumps(stor_data, protocol=5)
avserialiserad = pickle.loads(serialiserad)

print(np.array_equal(stor_data, avserialiserad))  # True

Fixad histogram-beräkning

Har du någonsin stött på out-of-memory-fel med np.histogram och data med väldigt låg variation? Det problemet är nu åtgärdat. Algoritmen för automatiskt binval har förbättrats:

import numpy as np

# Data med mycket låg variation — kunde orsaka problem i äldre versioner
data = np.full(10000, 42.0) + np.random.normal(0, 1e-10, 10000)

# Nu hanteras detta korrekt
antal, kanter = np.histogram(data, bins="auto")
print(f"Antal bins: {len(antal)}")

# För full kontroll, ange bins eller range explicit
antal2, kanter2 = np.histogram(data, bins=50, range=(41.9, 42.1))
print(f"Explicit antal bins: {len(antal2)}")

NumPy 2.4: Senaste versionen (december 2025)

Ny casting-typ: same_value

Den här funktionen är guld värd. NumPy 2.4 introducerar casting-typen same_value som kontrollerar att värdena faktiskt kan round-trip-castas utan förlust. Perfekt för att fånga buggar tidigt:

import numpy as np

# same_value — säkerställer att inga värden förändras
float_data = np.array([1.0, 2.0, 3.0])
int_data = float_data.astype(np.int64, casting="same_value")
print(int_data)  # [1 2 3] — fungerar, värdena är desamma

# Men om värden förändras:
float_data2 = np.array([1.5, 2.7, 3.9])
try:
    int_data2 = float_data2.astype(np.int64, casting="same_value")
except ValueError as e:
    print(f"Fel: {e}")
    # Värdena kan inte castas utan förlust

Snabbare np.unique för komplexa typer och strängar

np.unique har fått hash-baserad deduplicering för komplexa datatyper, bytesträngar, Unicode-strängar och StringDType. Det kan ge en rejäl speedup om du jobbar med stora datamängder.

import numpy as np

# Snabbare unika värden för komplexa tal
komplex_data = np.random.randn(100000) + 1j * np.random.randn(100000)
# Lägg till dubbletter
komplex_data = np.concatenate([komplex_data, komplex_data[:1000]])

unika = np.unique(komplex_data)
print(f"Antal unika: {len(unika)}")

# Snabbare unika värden för strängar
strang_data = np.array(["äpple", "banan", "äpple", "citron", "banan", "druva"])
unika_str = np.unique(strang_data)
print(unika_str)  # ['banan' 'citron' 'druva' 'äpple']

# Notera: hash-baserad metod garanterar INTE sorterad ordning
# Använd np.sort() efteråt om ordning behövs

Utökat np.size och np.pad

Två vanliga funktioner fick utökad funktionalitet — litet men välkommet:

import numpy as np

# np.size accepterar nu flera axlar
arr = np.zeros((3, 4, 5))
print(np.size(arr, axis=(0, 2)))  # 15 (3 * 5)

# np.pad accepterar nu dictionary för pad_width
data = np.array([[1, 2], [3, 4]])
# Padda med dictionary — nycklarna är axelindex
padded = np.pad(data, {0: (1, 1), 1: (2, 2)}, mode="constant")
print(padded.shape)  # (4, 6)
print(padded)
# [[0 0 0 0 0 0]
#  [0 0 1 2 0 0]
#  [0 0 3 4 0 0]
#  [0 0 0 0 0 0]]

Höjd CPU-baslinje för x86

Standardinställningen för cpu-baseline på x86 har höjts till x86-64-v2. Det innebär att NumPy nu kräver processorer från 2009 eller nyare (vilket knappast borde vara ett problem för de flesta). Äldre processorer stöds fortfarande genom att ange -Dcpu-baseline=none vid bygget.

Fri-trådad Python: Framtidens NumPy

Det här är nog det mest spännande som händer i NumPy-ekosystemet just nu. Varje version sedan 2.2 har förbättrat stödet för fri-trådad Python (free-threaded Python, även kallat "no-GIL") steg för steg.

Vad innebär fri-trådad Python?

Traditionellt har Pythons Global Interpreter Lock (GIL) begränsat verklig parallell exekvering av Python-kod. Med det experimentella fri-trådade läget i CPython 3.13+ kan flera trådar köra Python-kod på riktigt parallellt. Och det öppnar en hel del dörrar för NumPy.

import numpy as np
from concurrent.futures import ThreadPoolExecutor

# Med fri-trådad Python kan NumPy-operationer i olika trådar
# köras verkligt parallellt

def berakna_statistik(data):
    """Beräkna statistik för en datamängd."""
    return {
        "medel": np.mean(data),
        "std": np.std(data),
        "median": np.median(data),
        "min": np.min(data),
        "max": np.max(data)
    }

# Simulera flera parallella beräkningar
datamangder = [np.random.randn(1_000_000) for _ in range(8)]

with ThreadPoolExecutor(max_workers=8) as executor:
    resultat = list(executor.map(berakna_statistik, datamangder))

for i, r in enumerate(resultat[:3]):
    print(f"Dataset {i}: medel={r['medel']:.4f}, std={r['std']:.4f}")

NumPy 2.4 har gjort betydande framsteg i att förbättra trådsäkerheten för ufunc-operationer, och skalbarheten vid samtidig exekvering i flera trådar ser lovande ut.

Praktiskt migrationsexempel: Från NumPy 1.x till 2.x

Låt oss titta på ett realistiskt migrationsscenario. Det här är typ av kod man faktiskt stöter på i verkliga projekt:

# ============================================
# FÖRE MIGRATION (NumPy 1.x-kod)
# ============================================
import numpy as np

# Problem 1: Föråldrade typalias
data = np.array([1.0, 2.0], dtype=np.float)     # Borttagen i 2.0
mask = np.array([True, False], dtype=np.bool)    # Borttagen i 2.0
index = np.array([0, 1], dtype=np.int)           # Borttagen i 2.0

# Problem 2: Borttagna funktioner
resultat = np.cumproduct([1, 2, 3, 4])           # Borttagen
text = np.string_("hello")                        # Föråldrad

# Problem 3: Oförutsägbar typpromotion
a = np.array([1], dtype=np.int8)
b = a + 200   # Kunde ge int16 i 1.x

# Problem 4: Kontroll av tom array
tom = np.array([])
if not tom:   # Gav False i 1.x, fel i 2.2+
    print("Tom!")

# ============================================
# EFTER MIGRATION (NumPy 2.x-kod)
# ============================================
import numpy as np

# Lösning 1: Använd explicita typer
data = np.array([1.0, 2.0], dtype=np.float64)
mask = np.array([True, False], dtype=np.bool_)
index = np.array([0, 1], dtype=np.int64)

# Lösning 2: Använd aktuella funktionsnamn
resultat = np.cumprod([1, 2, 3, 4])
text = np.bytes_("hello")

# Lösning 3: Typpromotion är nu konsekvent
a = np.array([1], dtype=np.int8)
b = a + np.int16(200)  # Explicit om du behöver int16

# Lösning 4: Använd .size för kontroll
tom = np.array([])
if tom.size == 0:
    print("Tom!")

Prestandajämförelse: NumPy 1.26 vs 2.4

NumPy 2.x har fått en hel rad prestandaförbättringar under sin livstid. Här är ett enkelt benchmark-skript så du kan testa själv:

import numpy as np
import time

def benchmark(func, *args, n_iter=100):
    """Kör en funktion flera gånger och returnera medeltid."""
    tider = []
    for _ in range(n_iter):
        start = time.perf_counter()
        func(*args)
        slut = time.perf_counter()
        tider.append(slut - start)
    return np.median(tider)

# Testdata
stor_array = np.random.randn(5_000_000)
matris_a = np.random.randn(500, 500)
matris_b = np.random.randn(500, 500)

# Benchmark: sortering
t_sort = benchmark(np.sort, stor_array.copy())
print(f"np.sort (5M element): {t_sort*1000:.1f} ms")

# Benchmark: matris-vektorprodukt (ny i 2.2!)
vektor = np.random.randn(500)
t_matvec = benchmark(np.matvec, matris_a, vektor)
print(f"np.matvec (500x500 @ 500): {t_matvec*1000:.3f} ms")

# Benchmark: unika värden (förbättrad i 2.4)
med_dubbletter = np.random.randint(0, 10000, size=1_000_000)
t_unique = benchmark(np.unique, med_dubbletter)
print(f"np.unique (1M element): {t_unique*1000:.1f} ms")

# Benchmark: np.zeros med hugepages (förbättrad i 2.2)
t_zeros = benchmark(np.zeros, (10_000_000,))
print(f"np.zeros (10M element): {t_zeros*1000:.3f} ms")

Bästa praxis för NumPy 2.x

1. Var explicit med datatyper

Med de nya typpromotionsreglerna är det viktigare än någonsin att vara tydlig med vilka datatyper du arbetar med:

import numpy as np

# Bra: explicit dtype
priser = np.array([19.99, 29.99, 39.99], dtype=np.float64)
antal = np.array([1, 2, 3], dtype=np.int32)

# Undvik: implicit dtype som kan överraska
# blandad = priser + antal  # Fungerar, men var medveten om resultatet
blandad = priser + antal.astype(np.float64)  # Tydligare

2. Utnyttja nya linjäralgebrafunktioner

Släpp de gamla omformningarna och använd de nya specialiserade funktionerna istället:

import numpy as np

A = np.random.randn(100, 3, 3)  # Batch av 100 matriser
v = np.random.randn(100, 3)     # Batch av 100 vektorer

# Gammalt sätt (kräver omformning):
# resultat = np.matmul(A, v[:, :, np.newaxis]).squeeze(-1)

# Nytt, tydligare sätt (NumPy 2.2+):
resultat = np.matvec(A, v)
print(resultat.shape)  # (100, 3)

3. Använd StringDType för textdata

StringDType erbjuder betydligt effektivare stränghantering jämfört med de gamla fast-bredds Unicode-typerna. Skillnaden i minnesanvändning kan vara dramatisk:

import numpy as np
from numpy.dtypes import StringDType

# Gammal stil — fixerad bredd, slöseri med minne
gammal = np.array(["kort", "ett mycket långt strängvärde här"], dtype="U50")
print(gammal.nbytes)  # 400 bytes (2 * 50 * 4)

# Ny stil — variabel längd, minneseffektivt
ny = np.array(["kort", "ett mycket långt strängvärde här"], dtype=StringDType())
print(ny.dtype)  # StringDType()

4. Hantera tomma arrayer korrekt

Det här är en av de vanligaste fallgroparna vid migration. Uppdatera all kod som använder boolesk kontroll av arrayer:

import numpy as np

def bearbeta_data(data):
    """Bearbeta en NumPy-array med korrekt tomhetskontroll."""
    # Fel i NumPy 2.2+:
    # if not data:
    #     return None

    # Korrekt:
    if data.size == 0:
        return None

    # Eller med len() för 1D:
    if len(data) == 0:
        return None

    return np.mean(data)

5. Fånga dataförlust med same_value

Använd den nya casting-typen för att upptäcka potentiella dataförluster tidigt i din pipeline:

import numpy as np

def saker_konvertering(data, mal_dtype):
    """Konvertera array med garanti att inga värden förändras."""
    try:
        return data.astype(mal_dtype, casting="same_value")
    except ValueError:
        print(f"Varning: Kan inte konvertera från {data.dtype} "
              f"till {mal_dtype} utan dataförlust")
        return data

# Exempel
float_data = np.array([1.0, 2.5, 3.0])
int_resultat = saker_konvertering(float_data, np.int64)
# Varning: Kan inte konvertera utan dataförlust (2.5 -> 2)

Integration med det bredare ekosystemet

En NumPy-uppgradering påverkar hela det vetenskapliga Python-ekosystemet. Här är läget för de viktigaste paketen.

Pandas 3.0 och NumPy 2.x

Pandas 3.0 är fullt kompatibelt med NumPy 2.x och drar nytta av förbättringarna:

import numpy as np
import pandas as pd

# Pandas ArrowDtype och NumPy 2.x samarbetar väl
df = pd.DataFrame({
    "värde": np.array([1.0, 2.0, 3.0], dtype=np.float64),
    "text": pd.array(["a", "b", "c"], dtype="string[pyarrow]")
})

# NumPy-operationer på Pandas-kolumner fungerar sömlöst
resultat = np.mean(df["värde"].to_numpy())
print(resultat)  # 2.0

Scikit-learn och NumPy 2.x

Scikit-learn 1.8+ stödjer NumPy 2.x fullt ut, inklusive de nya Array API-funktionerna för GPU-acceleration:

import numpy as np
from sklearn.preprocessing import StandardScaler

# Standardisering med NumPy 2.x
data = np.random.randn(1000, 10).astype(np.float64)
scaler = StandardScaler()
normaliserad = scaler.fit_transform(data)

print(f"Medelvärde: {normaliserad.mean(axis=0)[:3]}")
print(f"Standardavvikelse: {normaliserad.std(axis=0)[:3]}")

Matplotlib och NumPy 2.x

Matplotlib fungerar sömlöst med NumPy 2.x och drar nytta av de förbättrade typannoteringarna:

import numpy as np

# Generera data med NumPy 2.x
x = np.linspace(0, 2 * np.pi, 100, dtype=np.float64)
y1 = np.sin(x)
y2 = np.cos(x)

# Matplotlib-kompatibel visualisering
# import matplotlib.pyplot as plt
# fig, ax = plt.subplots()
# ax.plot(x, y1, label="sin(x)")
# ax.plot(x, y2, label="cos(x)")
# ax.legend()
# plt.show()

Steg-för-steg migrationsstrategi

Att migrera ett större projekt till NumPy 2.x kräver lite eftertanke. Här är en strategi som fungerat väl i praktiken:

  1. Börja med Ruff: Kör ruff check --preview --select NPY201 --fix för att automatiskt åtgärda de vanligaste problemen.
  2. Kör testsviten: Kör alla befintliga tester med NumPy 2.x installerat och notera eventuella fel.
  3. Kontrollera typpromotion: Sök efter ställen där din kod blandar skalära värden med arrayer av specifika typer, särskilt int8, int16 och float32.
  4. Uppdatera booleska kontroller: Sök efter if array: eller if not array: och ersätt med .size-kontroller.
  5. Granska C-tillägg: Om ditt projekt har C-tillägg, kontrollera kompatibiliteten med PyArray_Descr-ändringarna.
  6. Testa med CI: Lägg till NumPy 2.x i din CI/CD-pipeline som en testmatris.
# Exempel: CI/CD-konfiguration med GitHub Actions
# .github/workflows/test.yml
#
# strategy:
#   matrix:
#     numpy-version: ["1.26", "2.4"]
# steps:
#   - name: Installera NumPy
#     run: pip install "numpy==${{ matrix.numpy-version }}.*"
#   - name: Kör tester
#     run: pytest tests/

Sammanfattning och framtidsutsikter

NumPy 2.x-serien är ett rejält steg framåt för Pythons vetenskapliga beräkningsekosystem. Här är det viktigaste att ta med sig:

  • NumPy 2.0 — Genomgripande API-uppstädning, nya typpromotionsregler (NEP 50), publikt DType API (NEP 42), StringDType (NEP 55) och ABI-brott.
  • NumPy 2.2 — Nya matvec/vecmat-funktioner, förbättrade typannoteringar, beteendeändring för tomma arrayer och förbättrad array-representation.
  • NumPy 2.3 — OpenMP-stöd för parallell sortering, kopieringsfri pickling och fixad histogram-beräkning.
  • NumPy 2.4 — Ny same_value casting, hash-baserad np.unique för fler typer, utökat DType API och höjd CPU-baslinje.

Framöver är fri-trådad Python det mest spännande utvecklingsområdet. Med CPython 3.14 och dess stöd för GIL-fritt läge förväntas NumPy kunna leverera ännu bättre parallellprestanda. DType API:et fortsätter också att mogna, vilket öppnar för helt nya datatyper — från kvantifieringstyper för maskininlärning till specialiserade vetenskapliga format.

Min rekommendation? Börja migreringen nu. Använd Ruff för automatisk koduppdatering, testa ordentligt, och utnyttja de nya funktionerna och prestandaförbättringarna. Dina datavetenskapliga arbetsflöden kommer tacka dig.

Om Författaren Editorial Team

Our team of expert writers and editors.