Ik wil graag weten hoe ik een panda-dataframe kan converteren naar een NumPy-array.
dataframe:
import numpy as np
import pandas as pd
index = [1, 2, 3, 4, 5, 6, 7]
a = [np.nan, np.nan, np.nan, 0.1, 0.1, 0.1, 0.1]
b = [0.2, np.nan, 0.2, 0.2, 0.2, np.nan, np.nan]
c = [np.nan, 0.5, 0.5, np.nan, 0.5, 0.5, np.nan]
df = pd.DataFrame({'A': a, 'B': b, 'C': c}, index=index)
df = df.rename_axis('ID')
geeft
label A B C
ID
1 NaN 0.2 NaN
2 NaN NaN 0.5
3 NaN 0.2 0.5
4 0.1 0.2 NaN
5 0.1 0.2 0.5
6 0.1 NaN 0.5
7 0.1 NaN NaN
Ik wil dit graag converteren naar een NumPy-array, als volgt:
array([[ nan, 0.2, nan],
[ nan, nan, 0.5],
[ nan, 0.2, 0.5],
[ 0.1, 0.2, nan],
[ 0.1, 0.2, 0.5],
[ 0.1, nan, 0.5],
[ 0.1, nan, nan]])
Hoe kan ik dit doen?
Als een bonus, is het mogelijk om de dtypes op deze manier te behouden?
array([[ 1, nan, 0.2, nan],
[ 2, nan, nan, 0.5],
[ 3, nan, 0.2, 0.5],
[ 4, 0.1, 0.2, nan],
[ 5, 0.1, 0.2, 0.5],
[ 6, 0.1, nan, 0.5],
[ 7, 0.1, nan, nan]],
dtype=[('ID', '<i4'), ('A', '<f8'), ('B', '<f8'), ('B', '<f8')])
of vergelijkbaar?
Antwoord 1, autoriteit 100%
Gebruik deze code om een panda-dataframe (df) naar een numpy ndarray te converteren:
df.values
array([[nan, 0.2, nan],
[nan, nan, 0.5],
[nan, 0.2, 0.5],
[0.1, 0.2, nan],
[0.1, 0.2, 0.5],
[0.1, nan, 0.5],
[0.1, nan, nan]])
2, Autoriteit 99%
df.to_numpy()
is beter dan df.values
, hier is waarom. * sup>
Het is tijd om uw gebruik van values
en as_matrix()
.
te verwijderen
Panda’s v0.24.0
Introducties twee nieuwe methoden voor het verkrijgen van numpy arrays van Panda’s Objects:
to_numpy()
, die is gedefinieerd opIndex
,Series
, ENDataFrame
Objecten enarray
, die is gedefinieerd metIndex
enSeries
Objecten alleen.
Als u de V0.24-documenten bezoekt voor .values
, u ziet een grote rode waarschuwing die zegt:
WAARSCHUWING: we raden u aan
DataFrame.to_numpy()
in plaats daarvan te gebruiken.
Zie Dit gedeelte van de V0.24.0-release-opmerkingen , en dit antwoord voor meer informatie.
* – to_numpy()
is mijn aanbevolen methode voor elke productiecode die betrouwbaar moet worden uitgevoerd voor vele versies in de toekomst. Als u echter gewoon een ScratchPad in Jupyter of de Terminal maakt, is het gebruik van .values
om een paar milliseconden van typen op te slaan, een toegestane uitzondering. U kunt de fit n altijd later toevoegen.
Naar een betere consistentie: to_numpy()
In de geest van een betere consistentie in de hele API, is een nieuwe methode to_numpy
geïntroduceerd om de onderliggende NumPy-array uit DataFrames te extraheren.
# Setup
df = pd.DataFrame(data={'A': [1, 2, 3], 'B': [4, 5, 6], 'C': [7, 8, 9]},
index=['a', 'b', 'c'])
# Convert the entire DataFrame
df.to_numpy()
# array([[1, 4, 7],
# [2, 5, 8],
# [3, 6, 9]])
# Convert specific columns
df[['A', 'C']].to_numpy()
# array([[1, 7],
# [2, 8],
# [3, 9]])
Zoals hierboven vermeld, is deze methode ook gedefinieerd voor Index
– en Series
-objecten (zie hier).
df.index.to_numpy()
# array(['a', 'b', 'c'], dtype=object)
df['A'].to_numpy()
# array([1, 2, 3])
Standaard wordt een weergave geretourneerd, dus eventuele wijzigingen hebben invloed op het origineel.
v = df.to_numpy()
v[0, 0] = -1
df
A B C
a -1 4 7
b 2 5 8
c 3 6 9
Als je in plaats daarvan een kopie nodig hebt, gebruik dan to_numpy(copy=True)
.
panda’s >= 1.0 update voor ExtensionTypes
Als je panda’s 1.x gebruikt, is de kans groot dat je veel meer met extensietypen te maken krijgt. Je moet wat voorzichtiger zijn dat deze extensietypes correct worden geconverteerd.
a = pd.array([1, 2, None], dtype="Int64")
a
<IntegerArray>
[1, 2, <NA>]
Length: 3, dtype: Int64
# Wrong
a.to_numpy()
# array([1, 2, <NA>], dtype=object) # yuck, objects
# Correct
a.to_numpy(dtype='float', na_value=np.nan)
# array([ 1., 2., nan])
# Also correct
a.to_numpy(dtype='int', na_value=-1)
# array([ 1, 2, -1])
Dit is geroepen in de documenten.
Als je de dtypes
nodig hebt in het resultaat…
Zoals blijkt uit een ander antwoord, DataFrame.to_records
is een goede manier om dit te doen.
df.to_records()
# rec.array([('a', 1, 4, 7), ('b', 2, 5, 8), ('c', 3, 6, 9)],
# dtype=[('index', 'O'), ('A', '<i8'), ('B', '<i8'), ('C', '<i8')])
Dit kan helaas niet met to_numpy
. Als alternatief kunt u echter np.rec.fromrecords
gebruiken:
v = df.reset_index()
np.rec.fromrecords(v, names=v.columns.tolist())
# rec.array([('a', 1, 4, 7), ('b', 2, 5, 8), ('c', 3, 6, 9)],
# dtype=[('index', '<U1'), ('A', '<i8'), ('B', '<i8'), ('C', '<i8')])
Performance Wise, het is bijna hetzelfde (eigenlijk, met rec.fromrecords
is een beetje sneller).
df2 = pd.concat([df] * 10000)
%timeit df2.to_records()
%%timeit
v = df2.reset_index()
np.rec.fromrecords(v, names=v.columns.tolist())
12.9 ms ± 511 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
9.56 ms ± 291 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Rationale voor het toevoegen van een nieuwe methode
to_numpy()
(in aanvulling op array
) is toegevoegd als gevolg van discussies onder twee GitHub-problemen GH19954 en GH23623 .
Specifiek vermelden de DOCS de reden:
[…] met
.values
het was onduidelijk of de geretourneerde waarde de
Werkelijke array, enige transformatie ervan, of een van Pandas Custom
Arrays (zoalsCategorical
). Bijvoorbeeld, metPeriodIndex
,.values
Genereert elke keer een nieuwendarray
van periodeobjecten. […]
to_numpy
is bedoeld om de consistentie van de API te verbeteren, wat een belangrijke stap in de goede richting is. .values
WORDT NIET VERDELD IN DE HUIDIGE VERSIE, maar ik verwacht dat dit op een bepaald moment in de toekomst kan gebeuren, dus ik zou u willen dringen om zo snel mogelijk naar de nieuwere API te migreren naar de nieuwere API.
kritiek op andere oplossingen
DataFrame.values
heeft inconsistent gedrag, zoals reeds opgemerkt.
DataFrame.get_values()
is gewoon een wikkel rond DataFrame.values
, dus alles wat hierboven is gezegd, is van toepassing.
DataFrame.as_matrix()
wordt nu verouderd, doe niet Gebruik!
3, Autoriteit 29%
OPMERKING : de .as_matrix()
methode die in dit antwoord wordt gebruikt, wordt verouderd. Panda’s 0.23.4 waarschuwt:
METHODE
.as_matrix
wordt in een toekomstige versie verwijderd. Gebruik in plaats daarvan.
Panda’s heeft iets ingebouwd in …
numpy_matrix = df.as_matrix()
geeft
array([[nan, 0.2, nan],
[nan, nan, 0.5],
[nan, 0.2, 0.5],
[0.1, 0.2, nan],
[0.1, 0.2, 0.5],
[0.1, nan, 0.5],
[0.1, nan, nan]])
4, Autoriteit 17%
Ik zou gewoon de dataframe.reset_index () en Dataframe.Values functioneert om de numpy-weergave van het dataframe te krijgen, inclusief De index:
In [8]: df
Out[8]:
A B C
0 -0.982726 0.150726 0.691625
1 0.617297 -0.471879 0.505547
2 0.417123 -1.356803 -1.013499
3 -0.166363 -0.957758 1.178659
4 -0.164103 0.074516 -0.674325
5 -0.340169 -0.293698 1.231791
6 -1.062825 0.556273 1.508058
7 0.959610 0.247539 0.091333
[8 rows x 3 columns]
In [9]: df.reset_index().values
Out[9]:
array([[ 0. , -0.98272574, 0.150726 , 0.69162512],
[ 1. , 0.61729734, -0.47187926, 0.50554728],
[ 2. , 0.4171228 , -1.35680324, -1.01349922],
[ 3. , -0.16636303, -0.95775849, 1.17865945],
[ 4. , -0.16410334, 0.0745164 , -0.67432474],
[ 5. , -0.34016865, -0.29369841, 1.23179064],
[ 6. , -1.06282542, 0.55627285, 1.50805754],
[ 7. , 0.95961001, 0.24753911, 0.09133339]])
Om de dtypes te krijgen, moeten we deze ndarray transformeren in een gestructureerde array met behulp van bekijken:
In [10]: df.reset_index().values.ravel().view(dtype=[('index', int), ('A', float), ('B', float), ('C', float)])
Out[10]:
array([( 0, -0.98272574, 0.150726 , 0.69162512),
( 1, 0.61729734, -0.47187926, 0.50554728),
( 2, 0.4171228 , -1.35680324, -1.01349922),
( 3, -0.16636303, -0.95775849, 1.17865945),
( 4, -0.16410334, 0.0745164 , -0.67432474),
( 5, -0.34016865, -0.29369841, 1.23179064),
( 6, -1.06282542, 0.55627285, 1.50805754),
( 7, 0.95961001, 0.24753911, 0.09133339),
dtype=[('index', '<i8'), ('A', '<f8'), ('B', '<f8'), ('C', '<f8')])
5, Autoriteit 6%
Het lijkt als df.to_records()
zal voor u werken. De exacte functie U bent op zoek naar werd gevraagd en to_records
wees naar als alternatief.
Ik heb dit lokaal geprobeerd met behulp van uw voorbeeld, en die oproep levert iets op dezelfde manier op de uitvoer die u zoekt:
rec.array([(1, nan, 0.2, nan), (2, nan, nan, 0.5), (3, nan, 0.2, 0.5),
(4, 0.1, 0.2, nan), (5, 0.1, 0.2, 0.5), (6, 0.1, nan, 0.5),
(7, 0.1, nan, nan)],
dtype=[(u'ID', '<i8'), (u'A', '<f8'), (u'B', '<f8'), (u'C', '<f8')])
Merk op dat dit een recarray
is in plaats van een array
. U kunt het resultaat naar een gewone numpy-array verplaatsen door de constructor ervan aan te roepen als np.array(df.to_records())
.
Antwoord 6, autoriteit 4%
Probeer dit:
a = numpy.asarray(df)
Antwoord 7, autoriteit 2%
Hier is mijn benadering voor het maken van een structuurarray van een panda’s DataFrame.
Maak het dataframe
import pandas as pd
import numpy as np
import six
NaN = float('nan')
ID = [1, 2, 3, 4, 5, 6, 7]
A = [NaN, NaN, NaN, 0.1, 0.1, 0.1, 0.1]
B = [0.2, NaN, 0.2, 0.2, 0.2, NaN, NaN]
C = [NaN, 0.5, 0.5, NaN, 0.5, 0.5, NaN]
columns = {'A':A, 'B':B, 'C':C}
df = pd.DataFrame(columns, index=ID)
df.index.name = 'ID'
print(df)
A B C
ID
1 NaN 0.2 NaN
2 NaN NaN 0.5
3 NaN 0.2 0.5
4 0.1 0.2 NaN
5 0.1 0.2 0.5
6 0.1 NaN 0.5
7 0.1 NaN NaN
Definieer functie om een numpy structure array (geen record array) te maken van een panda’s DataFrame.
def df_to_sarray(df):
"""
Convert a pandas DataFrame object to a numpy structured array.
This is functionally equivalent to but more efficient than
np.array(df.to_array())
:param df: the data frame to convert
:return: a numpy structured array representation of df
"""
v = df.values
cols = df.columns
if six.PY2: # python 2 needs .encode() but 3 does not
types = [(cols[i].encode(), df[k].dtype.type) for (i, k) in enumerate(cols)]
else:
types = [(cols[i], df[k].dtype.type) for (i, k) in enumerate(cols)]
dtype = np.dtype(types)
z = np.zeros(v.shape[0], dtype)
for (i, k) in enumerate(z.dtype.names):
z[k] = v[:, i]
return z
Gebruik reset_index
om een nieuw gegevensframe te maken dat de index als onderdeel van de gegevens bevat. Converteer dat dataframe naar een structuurarray.
sa = df_to_sarray(df.reset_index())
sa
array([(1L, nan, 0.2, nan), (2L, nan, nan, 0.5), (3L, nan, 0.2, 0.5),
(4L, 0.1, 0.2, nan), (5L, 0.1, 0.2, 0.5), (6L, 0.1, nan, 0.5),
(7L, 0.1, nan, nan)],
dtype=[('ID', '<i8'), ('A', '<f8'), ('B', '<f8'), ('C', '<f8')])
EDIT: df_to_sarray bijgewerkt om fouten bij het bellen van .encode() met python 3 te voorkomen. Met dank aan Joseph Garvinen halcyonvoor hun commentaar en oplossing.
Antwoord 8, autoriteit 2%
Een eenvoudigere manier voor een voorbeelddataframe:
df
gbm nnet reg
0 12.097439 12.047437 12.100953
1 12.109811 12.070209 12.095288
2 11.720734 11.622139 11.740523
3 11.824557 11.926414 11.926527
4 11.800868 11.727730 11.729737
5 12.490984 12.502440 12.530894
GEBRUIK:
np.array(df.to_records().view(type=np.matrix))
KRIJG:
array([[(0, 12.097439 , 12.047437, 12.10095324),
(1, 12.10981081, 12.070209, 12.09528824),
(2, 11.72073428, 11.622139, 11.74052253),
(3, 11.82455653, 11.926414, 11.92652727),
(4, 11.80086775, 11.72773 , 11.72973699),
(5, 12.49098389, 12.50244 , 12.53089367)]],
dtype=(numpy.record, [('index', '<i8'), ('gbm', '<f8'), ('nnet', '<f4'),
('reg', '<f8')]))
9, Autoriteit 2%
Twee manieren om het gegevensframe om te zetten naar de numpy-array-weergave.
-
mah_np_array = df.as_matrix(columns=None)
-
mah_np_array = df.values
DOC: HTTPS: //PANDAS.PYDATA. Org / Panda’s-Docs / Stable / Gegenereerd / Pandas.Dataframe.as_Matrix.html
10
Had gewoon een soortgelijk probleem bij het exporteren van Dataframe naar Arcgis Table en struikelde op een oplossing van USGS (https://my.USGS.gov/confluence/display/cdi/pandas.dataframe+to+arcgis+table ).
Kortom uw probleem heeft een vergelijkbare oplossing:
df
A B C
ID
1 NaN 0.2 NaN
2 NaN NaN 0.5
3 NaN 0.2 0.5
4 0.1 0.2 NaN
5 0.1 0.2 0.5
6 0.1 NaN 0.5
7 0.1 NaN NaN
np_data = np.array(np.rec.fromrecords(df.values))
np_names = df.dtypes.index.tolist()
np_data.dtype.names = tuple([name.encode('UTF8') for name in np_names])
np_data
array([( nan, 0.2, nan), ( nan, nan, 0.5), ( nan, 0.2, 0.5),
( 0.1, 0.2, nan), ( 0.1, 0.2, 0.5), ( 0.1, nan, 0.5),
( 0.1, nan, nan)],
dtype=(numpy.record, [('A', '<f8'), ('B', '<f8'), ('C', '<f8')]))
11
Probeer dit:
np.array(df)
array([['ID', nan, nan, nan],
['1', nan, 0.2, nan],
['2', nan, nan, 0.5],
['3', nan, 0.2, 0.5],
['4', 0.1, 0.2, nan],
['5', 0.1, 0.2, 0.5],
['6', 0.1, nan, 0.5],
['7', 0.1, nan, nan]], dtype=object)
Nog enkele informatie op: [https: // docs .cipy.org / doc / numpy / referentie / gegenereerd / numpy.array.html]
Geldig voor numpy 1.16.5 en panda’s 0.25.2.
12
Verder naar het antwoord van Meteore, vond ik de code
df.index = df.index.astype('i8')
werkt niet voor mij. Dus ik heb mijn code hier voor het gemak van anderen geplakt bij dit probleem.
city_cluster_df = pd.read_csv(text_filepath, encoding='utf-8')
# the field 'city_en' is a string, when converted to Numpy array, it will be an object
city_cluster_arr = city_cluster_df[['city_en','lat','lon','cluster','cluster_filtered']].to_records()
descr=city_cluster_arr.dtype.descr
# change the field 'city_en' to string type (the index for 'city_en' here is 1 because before the field is the row index of dataframe)
descr[1]=(descr[1][0], "S20")
newArr=city_cluster_arr.astype(np.dtype(descr))
13
Een eenvoudige manier om dataframe naar Numpy Array te converteren:
import pandas as pd
df = pd.DataFrame({"A": [1, 2], "B": [3, 4]})
df_to_array = df.to_numpy()
array([[1, 3],
[2, 4]])
Gebruik van to_numpy wordt aangemoedigd om de consistentie te behouden.
Referentie:
https://pandas.pydata.org/ Panda’s-Docs / Stable / Reference / API / Pandas.Dataframe.to_numpy.html