Я хотел бы выяснить, смогу ли я заставить работать следующее (Pandas 0.23.4). Любая помощь будет очень признательна.
import numpy as np
import pandas as pd
rows = 12
rng = pd.date_range('2011-01', periods=rows, freq='M')
df = pd.DataFrame(np.arange(rows), index=rng)
print(df.loc['2011-01'])
print(df.loc[np.datetime64('2011-01')])
Первый print делает то, что я ожидал: показывает все строки за январь 2011 года. Однако второй выдает KeyError, потому что значение отсутствует в индексе. Я надеялся, что он даст тот же результат, но после некоторого тестирования я понял, что он ищет точное совпадение 2011-01-01, которого нет в DataFrame. Я бы хотел, чтобы второй работал, чтобы я мог использовать numpy.arange или pandas.date_range для легкого создания массивов дат, которые я мог бы перебирать. У кого-нибудь это работает?
(Похоже на это работает, но только если у вас есть точное совпадение дат.)






используйте DatetimeIndex.to_period () & Период. Месяц
import numpy as np
import pandas as pd
rows = 12
rng = pd.date_range('2011-01', periods=rows, freq='M')
df = pd.DataFrame(np.arange(rows), index=rng)
# print(df.loc['2011-01'])
for idx, di in enumerate(df.index.to_period()):
if di.month == np.datetime64('2011-01').item().month:
print(f'loc: [{idx}] == {df.index[idx]}')
выход:
# loc: [0] == 2011-01-31 00:00:00
Поскольку ваши индексы df состоят из дат конца месяца, вы можете использовать этот трюк, чтобы использовать df.loc для получения строки:
>>>> df.loc[df.index == np.datetime64('2011-03', 'D') -1]
0
2011-02-28 1
>>>> df.loc[df.index == np.datetime64('2011-04', 'D') -1]
0
2011-03-31 2
>>>> df[df.index == np.datetime64('2011-12', 'D') -1]
0
2011-11-30 10
# use 2012 January 1st minus one day to get 2011 Dec 31st
>>>> df[df.index == np.datetime64('2012-01', 'D') -1]
0
2011-12-31 11
Спасибо @cryptonome. Интересен метод to_period; Я должен это учитывать. Однако я надеялся найти способ сделать это без добавления еще одного явного цикла, если это возможно. Неявный цикл в Numpy / Pandas намного эффективнее ...
поскольку ваш индекс всегда указывает на конец месяца, а ваш np.datetime64 находится в формате year-month, вы можете использовать для этого трюк. позвольте мне отредактировать свой ответ.
Еще раз спасибо, @cryptonome. К сожалению, ваш новый код работает только для точных совпадений. Я надеялся провести поиск весь месяц. Тем не менее, я ценю вашу помощь.
все в порядке @ Райан, может я неправильно понял твой вопрос
Вы можете написать функцию для преобразования np.datetime64 в строки, совместимые с Pandas:
def stringify(x):
year = x.astype('datetime64[Y]').astype(int) + 1970
month = x.astype('datetime64[M]').astype(int) % 12 + 1
return f'{year}-{month:02}'
a = df.loc['2011-01']
b = df.loc[stringify(np.datetime64('2011-01'))]
assert a.equals(b)
Спасибо за помощь cryptonome и jpp. К сожалению, похоже, что ответ для этой конкретной версии Pandas - «Нет. Вы не можете сделать это точно». Я отметил ответ jpp как правильный, потому что для него не требуется еще один цикл.