#python-3.x #pandas #numpy
#python-3.x #pandas #numpy
Вопрос:
Ниже приведен фрагмент, который преобразует данные в массив NumPy. Затем он преобразуется в фрейм данных Pandas, где я намереваюсь его обработать. Я пытаюсь преобразовать его обратно в массив NumPy. Я терплю неудачу в этом. Плохо.
import pandas as pd
import numpy as np
from pprint import pprint
data = [
('2020-11-01 00:00:00', 1.0),
('2020-11-02 00:00:00', 2.0)
]
coordinatesType = [('timestamp', 'datetime64[s]'), ('value', '<f8')]
npArray = np.asarray(data, coordinatesType)
df = pd.DataFrame(data = npArray)
# do some pandas processing, then convert back to a numpy array
mutatedNpArray = df.to_numpy(coordinatesType)
pprint(mutatedNpArray)
# don't suply dtype for kicks
pprint(df.to_numpy())
Это дает crazytown:
array([[('2020-11-01T00:00:00', 1.6041888e 18),
('1970-01-01T00:00:01', 1.0000000e 00)],
[('2020-11-02T00:00:00', 1.6042752e 18),
('1970-01-01T00:00:02', 2.0000000e 00)]],
dtype=[('timestamp', '<M8[s]'), ('value', '<f8')])
array([[Timestamp('2020-11-01 00:00:00'), 1.0],
[Timestamp('2020-11-02 00:00:00'), 2.0]], dtype=object)
Я понимаю, что фрейм данных — это действительно причудливый массив NumPy под капотом, но я возвращаюсь к функции, которая принимает простой массив NumPy. Очевидно, что я неправильно обрабатываю dtypes и / или я не понимаю структуру данных внутри моего фрейма данных. Ниже показано, что ожидает вызываемая функция:
[('2020-11-01T00:00:00', 1.000 ),
('2020-11-02T00:00:00', 2.000 )],
dtype=[('timestamp', '<M8[s]'), ('value', '<f8')])
Я действительно не понимаю, как это сделать. Или что я должен делать вместо этого.
Помогите!
Как предложил @hpaul, я попробовал следующее:
# ...
df = df.set_index('timestamp')
# do some pandas processing, then convert back to a numpy array
mutatedNpArray = df.to_records(coordinatesType)
# ...
Все хорошо!
Комментарии:
1. Ищите
to_records
метод. Не забудьте прочитать документы. Возможно, вы сможете указатьdtype
, как вы делали изначально.
Ответ №1:
Помимо to_records
подхода, упомянутого в комментариях, вы можете сделать:
df.apply(tuple, axis=1).to_numpy(coordinatesType)
Вывод:
array([('2020-11-01T00:00:00', 1.), ('2020-11-02T00:00:00', 2.)],
dtype=[('timestamp', '<M8[s]'), ('value', '<f8')])
Соображения:
Я полагаю, что проблема здесь связана с разницей между исходным массивом и фреймом данных.
Форма вашего исходного массива numpy (2,)
, где каждое значение является кортежем. При создании фрейма данных оба df.shape
и df.to_numpy()
формы (2, 2)
таковы, что dtype
конструктор работает не так, как ожидалось. При преобразовании строк в кортежи в a pd.Series
вы получаете исходную форму (2,)
.