Pythoni c способ добавить метки времени к pandas кадрам данных на основе других меток времени - PullRequest
0 голосов
/ 15 апреля 2020

Фанкий способ, которым вы индексируете в pandas фреймы данных для изменения значений, сложен для меня. Я никогда не могу понять, изменяю ли я значение элемента dataframe или меняю копию этого значения.

Я также новичок в синтаксисе python для работы с массивами и изо всех сил пытаюсь превратить циклы над индексами (как в C ++) в векторные операции в python. Моя проблема в том, что я sh хочу добавить столбец значений pandas.Timestamp к кадру данных на основе значений в других столбцах. Допустим, я начинаю с фрейма данных, например

import pandas as pd
import numpy as np
mydata = np.transpose([ [11, 22, 33, 44, 66, 77],
         pd.to_datetime(['2015-02-26', '2015-02-27', '2015-02-25', np.NaN, '2015-01-24', '2015-03-24'], errors='coerce'),
         pd.to_datetime(['2015-02-24', np.NaN, '2015-03-24', '2015-02-26', '2015-02-27', '2015-02-25'], errors='coerce')
       ])

df = pd.DataFrame(columns=['ID', 'BEFORE', 'AFTER'], data=mydata)

df.head(6)

, который возвращает

    ID  BEFORE      AFTER
0   11  2015-02-26  2015-02-24
1   22  2015-02-27  NaT
2   33  2015-02-25  2015-03-24
3   44  NaT         2015-02-26
4   66  2015-01-24  2015-02-27
5   77  2015-03-24  2015-02-25

Я хочу найти меньшую из дат ДО и ПОСЛЕ, а затем создать новый столбец с именем RELEVANT_DATE с Результаты. Я могу тогда бросить ДО и ПОСЛЕ. Есть миллионы способов сделать это, но для меня почти все они не работают. Лучшее, что я могу сделать - это

# fix up NaT's only in specific columns, real data has more columns
futureDate = pd.to_datetime('2099-01-01')
df.fillna({'BEFORE':futureDate, 'AFTER':futureDate}, inplace=True)

# super clunky solution
numRows = np.shape(df)[0]
relevantDate = []
for index in range(numRows):
    if df.loc[index, 'AFTER'] >= df.loc[index, 'BEFORE']:
        relevantDate.append(df.loc[index, 'BEFORE'])
    else:
        relevantDate.append(df.loc[index, 'AFTER'])

# add relevant date column to df
df['RELEVANT_DATE'] = relevantDate

# delete irrelevant dates
df.drop(labels=['BEFORE', 'AFTER'], axis=1, inplace=True)

df.head(6)

, возвращающий

    ID  RELEVANT_DATE
0   11  2015-02-24
1   22  2015-02-27
2   33  2015-02-25
3   44  2015-02-26
4   66  2015-01-24
5   77  2015-02-25

Этот подход очень медленный. С несколькими миллионами строк это занимает слишком много времени, чтобы быть полезным.

Можете ли вы предоставить для этого решение в стиле pythoni c? Вспомните, что у меня проблемы как с векторизацией этих операций, так и с тем, чтобы в DataFrame они были установлены по-настоящему.

1 Ответ

1 голос
/ 15 апреля 2020

Возьмите минимум через ряд (axis=1). Установите индекс, чтобы вы могли взять с собой 'ID' для поездки.

df.set_index('ID').min(axis=1).rename('RELEVANT DATE').reset_index()

   ID RELEVANT DATE
0  11    2015-02-24
1  22    2015-02-27
2  33    2015-02-25
3  44    2015-02-26
4  66    2015-01-24
5  77    2015-02-25

Или назначить новый столбец существующему фрейму данных:

df['RELEVANT DATE'] = df[['BEFORE', 'AFTER']].min(1)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...