返回分组中字符串最终出现的语法

时间:2018-08-02 17:12:15

标签: python pandas numpy dataframe group-by

Date_Time      Position Trade
7/16/2018 13:00 Long    1
7/16/2018 13:30 Flat    1
7/16/2018 14:00 Flat    1
7/16/2018 14:30 Long    2
7/16/2018 15:00 Long    2
7/16/2018 15:30 Long    2
7/16/2018 17:00 Short   3
7/16/2018 17:30 Short   3
7/16/2018 18:00 Short   3
7/16/2018 18:30 Short   3
7/16/2018 19:00 Short   3
7/16/2018 19:30 Long    4
7/16/2018 20:00 Long    4
7/16/2018 20:30 Long    4
7/16/2018 21:00 Long    4
7/16/2018 21:30 Short   5
7/16/2018 22:00 Short   5
7/16/2018 22:30 Short   5
7/16/2018 23:00 Short   5
7/16/2018 23:30 Short   5
7/17/2018 0:00  Short   5
7/17/2018 0:30  Short   5
7/17/2018 1:00  Short   5
7/17/2018 1:30  Short   5
7/17/2018 2:00  Short   5
7/17/2018 2:30  Long    6

我有一个类似上面的数据框。我正在尝试创建一个返回按行业分组的系列的函数。

def compact_view(groupby):
agg_dict = {'EntryTime': groupby.iloc[0, :].name,
            'Trade Type': groupby['Position'].iat[0],
            'Size': groupby['Size'].iat[0],


            }

return pd.Series(agg_dict, index=['EntryTime', 'Trade Type', 'Size', 'ExitTime'])
compact_results = results.groupby(['Trades']).apply(compact_view)

我在处理系列项目之一的语法时遇到麻烦。

我想要一行名为“ ExitTime”的行,该行会在我的字典中的compact_view函数中使用,并返回该行中每个单词“ Long”或“ Short”的最终位置下方的行的索引值贸易号码。

所以第一个是7/16/2018 13:30。第二个是7/16/2018 17:00等

预期结果:

Trades  EntryTime   Trade Type  Size    ExitTime
0   7/16/2018 3:30  Flat    0   
1   7/16/2018 13:00 Long    5   7/16/2018 13:30
2   7/16/2018 14:30 Long    5   7/16/2018 17:00
3   7/16/2018 17:00 Short   -5  7/16/2018 19:30
4   7/16/2018 19:30 Long    5   7/16/2018 21:30
5   7/16/2018 21:30 Short   -5  7/17/2018 2:30
6   7/17/2018 2:30  Long    5   7/17/2018 4:30

2 个答案:

答案 0 :(得分:1)

IIUUC,在每个贸易组中,您需要找到LongShort出现的最后一个索引,然后在其下找到一行。

很多事情都会出错,我不知道您要如何处理。

  • 如果Trade组从不包含LongShort,会发生什么情况。 (当前,这将引发并IndexError
  • 如果DataFrame中的最后一行是LongShort
  • ,您想做什么?

因此,您可以添加例外来分别处理这些情况(例如try和except)。至少从示例数据中,您可以执行以下操作:

ids = df.reset_index().groupby('Trade').apply(lambda x: x[x.Position.isin(['Long', 'Short'])].index[-1]+1)
df.reset_index().reindex(ids)['Date_Time']

输出:

1    2018-07-16 13:30:00
6    2018-07-16 17:00:00
11   2018-07-16 19:30:00
15   2018-07-16 21:30:00
25   2018-07-17 02:30:00
26                   NaT
Name: Date_Time, dtype: datetime64[ns]

现在,您可以根据需要将它们加入聚合结果中。如您所见,我的最后一行是NaT,因为Long

中第6组的最后一个DataFrame值之后没有行

一种更安全的方法可能是:

def next_id(x):
    try:
        return x[x.Position.isin(['Long', 'Short'])].index[-1]+1
    except IndexError:
        pass

ids = df.reset_index().groupby('Trade').apply(lambda x: next_id(x))

答案 1 :(得分:0)

您可以使用pandas.DataFrame.drop_duplicates()识别块中的最后一行:

df.drop_duplicates(subset=['Position','Trade'],keep='last')

因此要获取下一行索引:

row_indices = [x+1 for x in df.drop_duplicates(
    subset=['Position','Trade'],keep='last').index.get_values()]