【问题标题】:Create ID column in a pandas dataframe在熊猫数据框中创建 ID 列
【发布时间】:2020-11-17 14:13:14
【问题描述】:

我有一个包含交易日志的数据框。我的问题是我没有任何 ID 来匹配股票的买卖。股票可以交易多次,我希望有一个 ID 来匹配每笔已完成的交易。 我的原始数据框是带有时间戳的顺序时间序列数据框。下面的例子说明了我的问题,我需要按顺序匹配和 ID 交易的股票。 非常简单的例子:

df1 = pd.DataFrame({'stock': ['A', 'B', 'C', 'A','C', 'A', 'A'],
                        'deal': ['buy', 'buy', 'buy', 'sell','sell', 'buy', 'sell']}) 
df1
Out[84]: 
  stock  deal
0     A   buy
1     B   buy
2     C   buy
3     A  sell
4     C  sell
5     A   buy
6     A  sell   
    

这是我想要的输出:

df1 = pd.DataFrame({'stock': ['A', 'B', 'C', 'A','C', 'A', 'A'],
                    'deal': ['buy', 'buy', 'buy', 'sell','sell', 'buy', 'sell'],
                    'ID': [1, 2, 3, 1,3, 4, 4]}) 


df1
Out[82]: 
  stock  deal  ID
0     A   buy   1
1     B   buy   2
2     C   buy   3
3     A  sell   1
4     C  sell   3
5     A   buy   4
6     A  sell   4

有什么想法吗?

【问题讨论】:

  • 没有数量,这是一个徒劳的目标。例如,今天可以买入股票 A,明天再买入,然后在第三天全部卖出。或者在再次买入之前卖出一半的头寸。或者可以通过卖空开仓。
  • 这只是一个简化的例子,原始的 df 包含你提到的内容。我已经涵盖了。不过评论很好!
  • 那么您可能应该根据累积数量何时达到零来确定您的标识符。
  • 您能否添加一个示例作为答案,不确定我是否关注..很高兴投票
  • 我可以稍后再添加一个。

标签: python pandas dataframe


【解决方案1】:

试试这个:

m = df1['deal'] == 'buy'
df1['ID'] = m.cumsum().where(m)
df1['ID'] = df1.groupby('stock')['ID'].ffill()

df1

输出:

  stock  deal   ID
0     A   buy  1.0
1     B   buy  2.0
2     C   buy  3.0
3     A  sell  1.0
4     C  sell  3.0
5     A   buy  4.0
6     A  sell  4.0

详情:

  • 创建一个布尔系列,True 其中deal 等于“购买”
  • Cumsum 并分配给“ID”以购买记录
  • 使用 groupby 和 ffill 将 'ID' 分配给下一个 'sell' 记录 buy '库存'

【讨论】:

  • 对于数据 df1 = pd.DataFrame({'stock': ['A', 'B', 'C', 'A','C', 'A', 'A'] , 'deal': ['buy', 'buy', 'buy', 'buy','sell', 'sell', 'sell']}) , 输出为:股票交易 ID 0 A 买入 1.0 1 B 买入2.0 2 C 买 3.0 3 A 买 4.0 4 C 卖 3.0 5 A 卖 4.0 6 A 卖 4.0 这是错误的。
  • 是的,按交易类型对交易进行排序不适用于此代码,但如果您按时间戳对交易进行排序,它将起作用。
【解决方案2】:

试试这个:

import pandas as pd
df1 = pd.DataFrame({'stock': ['A', 'B', 'C', 'A','C', 'A', 'A'],
                'deal': ['buy', 'buy', 'buy', 'sell','sell', 'buy', 'sell']})

def sequential_buy_sell_id_generator(df1):

    column_length = len(df1["stock"])
    found = [0]*column_length
    id = [0]*column_length

    counter = 0

    for row_pointer_head in range(column_length):
        if df1["deal"][row_pointer_head]=="buy":
            id[row_pointer_head]= counter
            counter+=1
            found[row_pointer_head] = 1
            id[row_pointer_head]= counter

            for row_pointer_tail in range(row_pointer_head+1, column_length):

                if df1["stock"][row_pointer_head]== df1["stock"][row_pointer_tail] and df1["deal"][row_pointer_tail] =="sell" and found[row_pointer_tail] == 0:
                    found[row_pointer_tail] = 1
                    id[row_pointer_tail]= counter
                    break

    df1 = df1.assign(id = id) 
    return df1


print(sequential_buy_sell_id_generator(df1))

输出:

enter code here
    stock  deal  id
0     A   buy   1
1     B   buy   2
2     C   buy   3
3     A  sell   1
4     C  sell   3
5     A   buy   4
6     A  sell   4

另一个例子:

For df1 = pd.DataFrame({'stock': ['A', 'B', 'C', 'A','C', 'A', 'A'],
                'deal': ['buy', 'buy', 'buy', 'buy','sell', 'sell', 'sell']})
  stock deal    ID
0   A   buy     1
1   B   buy     2
2   C   buy     3
3   A   buy     4
4   C   sell    3
5   A   sell    1
6   A   sell    4

【讨论】:

  • 啊,非常好的马希尔。
  • 试过了,结果不同。最后一个例子,结果是: print(sequential_buy_sell_id_generator(df1)) stock deal id 0 A buy 1 1 B buy 2 2 C buy 3 3 A buy 4 4 C sell 0 5 A sell 0 6 A sell 0 ,卖的是全0
  • 第二个“if”子句后的代码出现缩进错误,在stackoverflow中上传代码时发生。请立即查看代码
  • 找出此笔记本中的代码:colab.research.google.com/drive/…
猜你喜欢
  • 2016-08-28
  • 2019-12-21
  • 2019-06-07
  • 2016-08-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-16
  • 2019-01-25
相关资源
最近更新 更多