Припиніть використання valuesта as_matrix()!
pandas v0.24.0 представив два нові методи отримання масивів NumPy з об'єктів pandas:
to_numpy(), що визначено на Index, Series,і DataFrameоб'єкти, і
array, Який визначається на Indexі Seriesтільки об'єкти.
Якщо ви відвідаєте документи v0.24 для .values, ви побачите велике червоне попередження, яке говорить:
Попередження: радимо використовувати DataFrame.to_numpy()замість цього.
Дивіться цей розділ приміток до випуску v0.24.0 і цю відповідь для отримання додаткової інформації.
Назустріч кращій послідовності: to_numpy()
У дусі кращої послідовності в API to_numpyбуло введено новий метод для вилучення базового масиву NumPy з DataFrames.
# Setup.
df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]}, index=['a', 'b', 'c'])
df.to_numpy()
array([[1, 4],
[2, 5],
[3, 6]])
Як було сказано вище, цей метод також визначений на об'єктах Indexі Series(див. Тут ).
df.index.to_numpy()
# array(['a', 'b', 'c'], dtype=object)
df['A'].to_numpy()
# array([1, 2, 3])
За замовчуванням подання повертається, тому будь-які внесені зміни впливатимуть на оригінал.
v = df.to_numpy()
v[0, 0] = -1
df
A B
a -1 4
b 2 5
c 3 6
Якщо вам потрібна копія, використовуйте to_numpy(copy=True).
pandas> = 1,0 оновлення для ExtensionTypes
Якщо ви використовуєте панди 1.x, швидше за все, ви будете мати справу з типами розширень набагато більше. Вам доведеться бути трохи уважнішими, щоб ці типи розширень були правильно перетворені.
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
# Right
a.to_numpy(dtype='float', na_value=np.nan)
# array([ 1., 2., nan])
Це називається в документах .
Якщо вам потрібно dtypes...
Як показано в іншій відповіді, DataFrame.to_recordsце хороший спосіб зробити це.
df.to_records()
# rec.array([('a', -1, 4), ('b', 2, 5), ('c', 3, 6)],
# dtype=[('index', 'O'), ('A', '<i8'), ('B', '<i8')])
На to_numpyжаль, це неможливо зробити . Однак в якості альтернативи можна використовувати np.rec.fromrecords:
v = df.reset_index()
np.rec.fromrecords(v, names=v.columns.tolist())
# rec.array([('a', -1, 4), ('b', 2, 5), ('c', 3, 6)],
# dtype=[('index', '<U1'), ('A', '<i8'), ('B', '<i8')])
Ефективність, майже однакова (фактично, використання rec.fromrecordsтрохи швидше).
df2 = pd.concat([df] * 10000)
%timeit df2.to_records()
%%timeit
v = df2.reset_index()
np.rec.fromrecords(v, names=v.columns.tolist())
11.1 ms ± 557 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
9.67 ms ± 126 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Обґрунтування додавання нового методу
to_numpy()(на додаток до array) було додано в результаті обговорень під двома випусками GitHub GH19954 та GH23623 .
Конкретно в документах згадується обгрунтування:
[...] з .valuesним було незрозуміло, чи буде повернене значення фактичним масивом, деяким перетворенням його чи одним із користувацьких масивів панди (як Categorical). Наприклад, з PeriodIndex, кожного разу .values
створює нові ndarrayоб'єкти періоду. [...]
to_numpy прагнуть покращити узгодженість API, що є головним кроком у правильному напрямку. .valuesу поточній версії не буде застарілим, але я думаю, що це може статися в якийсь момент у майбутньому, тому я закликаю користувачів перейти до новішого API, як тільки ви зможете.
Критика інших рішень
DataFrame.values має непослідовну поведінку, як уже зазначалося.
DataFrame.get_values() це просто обгортка навколо DataFrame.values , тому все сказане вище стосується.
DataFrame.as_matrix()тепер застаріло, НЕ використовуйте!