Ну, вы могли делать:
var pairs = sequence.Select((value, index) => new { value, index } )
.GroupBy(x => x.index / 2, x => x.value)
В результате получается IGrouping<int, T>
с ключом 0, 1, 2 и т. д., и содержимое каждой группы один или два элемента.
Однако я мог бы написать собственный метод расширения:
public static IEnumerable<Tuple<T, T>> PairUp<T>(this IEnumerable<T> source)
{
using (var iterator = source.GetEnumerator())
{
while (iterator.MoveNext())
{
var first = iterator.Current;
var second = iterator.MoveNext() ? iterator.Current : default(T);
yield return Tuple.Create(first, second);
}
}
}
Это даст последовательность кортежей - недостатком здесь является то, что конечный кортеж будет иметь значение по умолчанию для T
как «второго» элемента, если последовательность имеет нечетное количество элементов. Для ссылочных типов, где последовательность состоит только из ненулевых значений, это нормально, но для некоторых последовательностей это не помогло.
Вы можете применять любую функцию, какую захотите. Некоторые из них уже реализованы для вас (например, mean
, sum
, но также first
и last
):
df.resample('D').first()
# values
# datetime
# 2018-05-08 0.1
Но вы можете просто применить любую функцию, какую захотите. будет передана вся группа для работы, как groupby
.
Например, последний раз перед 2 часами ночи (при условии, что кадр данных уже отсортирован по индексу):
import datetime
def last_before_2_am(group):
before_2_am = group[group.index.time < datetime.time(2, 0, 0)]
return before_2_am.iloc[-1]
df.resample('D').apply(last_before_2_am)
# values
# datetime
# 2018-05-08 0.5