多个.shift()操作互相覆盖

时间:2018-06-07 16:40:43

标签: python pandas

是否可以仅将移位应用于数据帧的某个子集?目前,以下内容将覆盖df ['结束']因为我直接将其分配给df ['结束'],但我无法弄清楚如何仅将其应用于较小的选择。

基本上我有一个日期列的数据,结束日期是下一行的开始日期,但仅限于某个类型的日期。最后一行应该使用相同的开始/结束。

对任何其他有关如何执行此操作的想法持开放态度!

示例数据

Start   Field
2018-05-22T19:03:30+0000    Product
2018-05-22T19:09:30+0000    Size
2018-05-22T19:09:30+0000    Category
2018-05-22T19:25:39+0000    Product
2018-05-22T19:42:41+0000    Size
2018-05-22T20:57:30+0000    Category

# First Shift
df['End'] = df.loc[df['Field'].isin(['Product', 'Category'])]['Start'].shift(periods=-1)

# Update last row  
shift_rows = df.loc[df['Field'].isin(['Product', 'Category'])]
df.iloc[-1, shift_rows.columns.get_loc('End')] = shift_rows.iloc[-1, df.columns.get_loc('Start')] 

# Second shift        
df['End'] = df.loc[df['Field'].isin(['Size'])['Start'].shift(periods=-1)

# Update last row
shift_rows = df.loc[df['Field'].isin(['Size'])]
df.iloc[-1, shift_rows.columns.get_loc('End')] = shift_rows.iloc[-1, df.columns.get_loc('Start')]

预期产出

Start   Field   End
2018-05-22T19:03:30+0000    Product 2018-05-22T19:09:30+0000
2018-05-22T19:09:30+0000    Size    2018-05-22T19:42:41+0000
2018-05-22T19:09:30+0000    Category    2018-05-22T19:25:39+0000
2018-05-22T19:25:39+0000    Product 2018-05-22T20:57:30+0000
2018-05-22T19:42:41+0000    Size    2018-05-22T19:42:41+0000
2018-05-22T20:57:30+0000    Category    2018-05-22T20:57:30+0000

1 个答案:

答案 0 :(得分:0)

一个想法可能是创建一个列Field_group,其中包含不同字段组的编号。您的样本:

window.require('fs')

如果你有两组以上的字段,你可以这样:

df['Field_group'] = df['Field'].apply(lambda field: 1 if field in ['Product', 'Category'] else 2)

现在您已拥有群组编号,您可以使用def associate_group_number (field): if field in ['Product', 'Category']: return 1 if field in ['Size','blabla']: return 2 if field in ['blo','bli','blu']: return 3 df['Field_group'] = df['Field'].apply(associate_group_number) groupby创建“结束”列,例如:

shift

并且因为您希望在df['End'] = df.groupby('Field_group')['Start'].shift(-1) 中的此行中填充每个组的End的最后一行(如果我理解的话),您可以使用Start

fillna

您甚至可以在前一行代码的df['End'] = df['End'].fillna(df['Start']) 之后添加.fillna(df['Start'])以便在一行中添加shift(-1),它可以工作(这里是解释)

最后,您可以删除使用以下内容创建的列:

df = df.drop('Field_group',1)