Привет, здесь возможное решение с использованием только панд.
Давайте дадим имя текущему индексу (для удобства и будем уверены, что мы все хорошо восстановим). Для сортировки по дате и применения функции к каждой группе важно отметить, что мы будем полагаться на тот факт, что панды сохраняют порядок строк внутри группы (см. документацию)
sorted_df = sorted_df = df.sort_values('Date')
result_df = sorted_df.groupby('A_key').apply(nearest_date_distance)
Так что теперь давайте посмотрим, что у нас есть внутри функции nearest_date_distance
Функция основана на том факте, что Дата будет отсортирована, поэтому мы вычисляем время до даты и время до даты после, разницу между текущим днем и следующим день отрицателен, поэтому мы добавляем .abs()
. Наконец, мы берем минимум между этими двумя расстояниями (кстати, оператор min не примет пропущенное значение (NaT), которое у вас есть для первой строки time_to_before и последней строки времени после)
def nearest_date_distance(sub):
time_to_before = sub['Date'].diff()
time_to_after = sub['Date'].diff(-1).abs()
nearest_date_distance = pd.concat([time_to_before, time_to_after],axis=1).min(axis=1)
nearest_date_distance.name = 'Distance'
return nearest_date_distance
Наконец, я немного соврал result_df
, это будет MultiIndex Serie (не датафрейм) этой формы:
A_key id
A1 0 145 days
1 145 days
A2 2 0 days
3 0 days
A3 4 163 days
5 26 days
6 26 days
A4 7 0 days
8 0 days
Мы можем легко преобразовать его в DataFrame, и правильное именование нашего исходного индекса помогает увидеть, что все проиндексировано так же, как в оригинальном df.
result_df =sorted_df.groupby('A_key').apply(nearest_date_distance).reset_index(level=0)
A_key Distance
id
0 A1 145 days
1 A1 145 days
2 A2 0 days
3 A2 0 days
4 A3 163 days
5 A3 26 days
6 A3 26 days
7 A4 0 days
8 A4 0 days
, и если вам нужна дата в итоговом кадре данных result_df['Date'] = df['Date']
, то добейтесь цели:)
В WPF существует Панель. Свойство ZIndex, которое можно установить в триггере:
<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid.Resources>
<x:Array x:Key="colors" Type="{x:Type Color}">
<Color>Green</Color>
<Color>Red</Color>
<Color>Blue</Color>
<Color>Orange</Color>
<Color>Yellow</Color>
<Color>Violet</Color>
</x:Array>
<DataTemplate DataType="{x:Type Color}">
<Border x:Name="brd" Height="20" Width="20">
<Border.Background>
<SolidColorBrush Color="{Binding}"/>
</Border.Background>
<Border.RenderTransform>
<ScaleTransform CenterX="10" CenterY="10"/>
</Border.RenderTransform>
<Border.Style>
<Style TargetType="{x:Type Border}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderThickness" Value="2"/>
<Setter Property="BorderBrush" Value="Black"/>
</Trigger>
</Style.Triggers>
</Style>
</Border.Style>
<Border.Triggers>
<EventTrigger RoutedEvent="Border.MouseEnter">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0.5" Storyboard.TargetName="brd" Storyboard.TargetProperty="RenderTransform.ScaleX" To="1.5"/>
<DoubleAnimation Duration="0:0:0.5" Storyboard.TargetName="brd" Storyboard.TargetProperty="RenderTransform.ScaleY" To="1.5"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="Border.MouseLeave">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0.5" Storyboard.TargetName="brd" Storyboard.TargetProperty="RenderTransform.ScaleX" To="1"/>
<DoubleAnimation Duration="0:0:0.5" Storyboard.TargetName="brd" Storyboard.TargetProperty="RenderTransform.ScaleY" To="1"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Border.Triggers>
</Border>
</DataTemplate>
<Style TargetType="{x:Type ContentPresenter}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Panel.ZIndex" Value="99999"/>
</Trigger>
</Style.Triggers>
</Style>
</Grid.Resources>
<ItemsControl ItemsSource="{StaticResource colors}" Margin="20" Width="40">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</Grid>
В Style
для ContentPresenter
мы устанавливаем Panel.ZIndex
на 99 999, когда IsMouseOver
true
. Это должно быть на ContentPresenter
а не Border
, потому что ContentPresenter
с являются детьми ItemsControl
панель.
, К сожалению, я не думаю, что это свойство добралось до Silverlight все же...
Во-первых, приложенное свойство Zindex определяется в Холст и таким образом не доступно в других производных Панели.
ItemsControl заказывает подэлементы согласно порядку списка. Первый Объект у основания стека и последнего на вершине. С данным, все, что необходимо сделать, удостоверяется, что выбранный пункт находится в нижней части списка.
Первый создают интерфейс для упорядочивания. Как это:
interface IOrderable
{
int theZOrder{get;set;}
}
Теперь реализация это в классе Вы показываете.
, Когда Вы захотите выявить объект, дайте ему высокое количество и дайте всем другим небольшое число.
Al там оставляют, фактическое упорядочивание. Добавьте что-то вроде этого, и Вы установлены:
ItemsCont.ItemsSource =
ItemsCont.Items.OrderByDesc(t=>((IOrderable)t).theZOrder);
Мне приходилось иметь дело с этим.
Допустим, у вас есть ItemsControl с ItemTemplate, установленным как экземпляр пользовательского элемента управления. В этом элементе управления вы выполняете Canvas.SetZIndex (this, 99). Это не сработает, потому что «this» не является непосредственным потомком ItemsPanel ItemsControl. ItemsControl создает ContentPresenter для каждого элемента, помещает его в ItemsPanel и отображает ItemTemplate в ContentPresenter.
Итак, если вы хотите изменить ZIndex в своем элементе управления, вам нужно найти его ContentPresenter и изменить ZIndex на том. Один из способов - это ...
public static T FindVisualParent<T>( this DependencyObject obj )
where T : DependencyObject
{
DependencyObject parent = VisualTreeHelper.GetParent( obj );
while ( parent != null )
{
T typed = parent as T;
if ( typed != null )
{
return typed;
}
parent = VisualTreeHelper.GetParent( parent );
}
return null;
}
ContentPresenter foo = this.FindVisualParent<ContentPresenter>();
Canvas.SetZIndex( foo, 99 );
Html работает точно так же. Все элементы списка должны быть одноуровневыми, если вы хотите расположить их слоями.
Я расширил приведенный выше код, чтобы он останавливался, если нашел (например) ItemsPresenter. Если ContentPresenter не отображается между здесь и ItemsPresenter, то вернусь к моему исходному коду.
void setZindex(MyLayeredType layeredObj, int index)
{
ContentPresenter sibbling =
FindVisualParent<ContentPresenter, ItemsPresenter>(layeredObj);
if (sibbling != null)
{
sibbling.SetValue(Canvas.ZIndexProperty, index);
}
else
{
layeredObj.SetValue(Canvas.ZIndexProperty, index);
}
}
public static T FindVisualParent<T,C>(this DependencyObject obj)
where T : DependencyObject
where C : DependencyObject
{
DependencyObject parent = VisualTreeHelper.GetParent(obj);
while (parent != null)
{
T typed = parent as T;
if (typed != null)
{
return typed;
}
C ceiling = parent as C;
if (ceiling != null)
return null;
parent = VisualTreeHelper.GetParent(parent);
}
return null;
}