Учитывая DatetimeIndex и коллекцию записей, учитывающих дату и время, как создать Pandas DataFrame? - PullRequest
0 голосов
/ 09 октября 2018

У меня есть предопределенный DatetimeIndex и список кортежей такого типа: (datetime, float, float, float).Мне нужно создать DataFrame Pandas и заполнить его данными из списка.Нет необходимости говорить, что первый элемент каждой записи (кортеж) определяет предполагаемую позицию в результирующем DataFrame, а не значение столбца, в результирующем DataFrame должно быть только 3 плавающих столбца.Записи, у которых нет соответствующего элемента в DatetimeIndex, должны быть отброшены (и я не возражаю против ошибки, которая возникает в таком случае).

Учитывая список самих кортежей pd.DataFrame.from_records()обрабатывает каждый элемент кортежа как значение столбца (и выдает ошибку, если я не включаю столбец datetime в список столбцов).

Учитывая словарь, определенный как {r[0]: (r[1], r[2], r[3]) for r in rs} (где rs - это исходный список кортежей) pd.DataFrame.from_records() возвращает DataFrame, где каждое значение в каждом поле каждого столбца равно NaN.Я также пытался использовать списки вместо кортежей ({r[0]: [r[1], r[2], r[3]] for r in rs}), но результат был тот же.Я дважды проверил - значения в исходных кортежах в значительной степени определены числами с плавающей точкой, и нет ни NaN, ни None.Установка coerce_float ничего не меняет.

ОБНОВЛЕНИЕ: я также пытался использовать словарь словарей для указания имен столбцов в соответствии со списком столбцов ({r[0]: {'A': r[1], 'B': r[2], 'C': r[3]} for r in rs}), и результат тот же - всеNaNs.

ОБНОВЛЕНИЕ: Вот пример:

dts = [
    datetime(2018, 1, 1, 0, 0, 0, 0, timezone.utc),
    datetime(2018, 1, 2, 0, 0, 0, 0, timezone.utc),
    datetime(2018, 1, 3, 0, 0, 0, 0, timezone.utc)
]

dti = pd.DatetimeIndex(dts, tz=timezone.utc)

rs = [
    (datetime(2018, 1, 1, 0, 0, 0, 0, timezone.utc), 0.1, 0.2, 0.3),
    (datetime(2018, 1, 2, 0, 0, 0, 0, timezone.utc), 0.4, 0.5, 0.6),
    (datetime(2018, 1, 3, 0, 0, 0, 0, timezone.utc), 0.7, 0.8, 0.9)
]

# ...

dtf = pd.DataFrame.from_records(rs, index=dti, columns=['A', 'B', 'C'], coerce_float=True)

print(dtf)

должен привести к

                           A    B    C  
2008-01-01 00:00:00+00:00  0.1  0.2  0.3
2008-01-02 00:00:00+00:00  0.3  0.5  0.6
2008-01-03 00:00:00+00:00  0.7  0.8  0.9

Но на самом деле это приведет к AssertionError: 3 columns passed, passed data had 4 columns, если выполняется таким образом.Что я должен написать вместо # ...?Или, возможно, что я должен использовать вместо from_records для достижения желаемого результата с учетом вводимых данных?

Ответы [ 2 ]

0 голосов
/ 09 октября 2018

Точное понимание, которое вы дали, предположительно дало бы вам столбцы, названные Datetime, а не строки, проиндексированные Datetime.Оставляя это в стороне, если вы можете создать DataFrame с 4 столбцами, вы просто должны иметь возможность использовать DataFrame.set_index , чтобы установить столбец Datetime в качестве индекса, и DataFrame.reindex индексировать по вашему DatetimeIndex.

Вы также можете сначала создать DataFrame и заполнить столбцы в цикле.Индексатор DataFrame.loc выдаст KeyError, если значение даты и времени не является ключом в индексе, и в этом случае вы можете просто попробовать следующий кортеж:

df = pd.DataFrame(index=my_datetime_index, columns=['val1', 'val2', 'val3'])
for r in rs:
    try:
        df.loc[r[0]] = r[1:]
    except KeyError:
        pass
0 голосов
/ 09 октября 2018

Предполагая, что заданный вами индекс даты и времени называется dti, просто создайте фрейм данных со списком кортежей, установите индекс для первого столбца даты и времени, а затем переиндексируйте dti:

df = pd.DataFrame(rs, columns=['datetime', 'A', 'B', 'C'])
>>> df.set_index('datetime').reindex(dti)
              A    B    C
2018-01-01  0.1  0.2  0.3
2018-01-02  0.3  0.5  0.6
2018-01-03  0.7  0.8  0.9
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...