映射到pandas中的同一数据帧列

时间:2017-03-14 10:18:01

标签: python pandas dictionary

我有一个如下的数据框

Token,Time,Path,Duration,Response
1, 142830,NaN , IOC, NEW
1,142832,0,NaN,NEW_CONFIRM
1,142836,1234,NaN,TRADED
2, 142830,NaN , IOC, NEW
2,142832,0,NaN,NEW_CONFIRM
2,142836,1234,NaN,NOT_TRADED
3, 142830,NaN , GTC, NEW
3,142832,0,NaN,NEW_CONFIRM
3,142836,1234,NaN,NOT_TRADED

我的目的是获取持续时间为IOC的所有令牌

orders = df.loc[df.Duration == 'IOC', 'Token'].unique()

从令牌处获取Path值,其中Response为CONFIRM(这很棘手) 返回类似下面的内容

Token,Time,Path,Duration,Response
1, 142830,0,IOC,TRADED
2, 142830,0,IOC,NOT_TRADED

每个令牌都将始终具有确认(如果不是则忽略该令牌)。每个令牌都可以交易或不交易。最后,我将分组Path 0中有多少令牌进行交易而不进行交易,类似于路径1,路径2等(但只有在响应类型确认的情况下才需要路径)任何其他路径值都可能是错误的(1234)是一个垃圾值)

添加新示例

>>> df
     OrderID            TimeStamp  ErrorCode Duration          ResponseType  \
0    3000000  1488948188555841641        NaN      IOC                   NaN   
1    3000000  1488948188556444675          0      NaN     NEW_ORDER_CONFIRM   
2    3000000  1488948188556448153          2      NaN         TRADE_CONFIRM   
3    3000001  1488948658787676012        NaN      IOC                   NaN   
4    3000001  1488948658787811582          1      NaN     NEW_ORDER_CONFIRM   
5    3000001  1488948658787824862          2      NaN         TRADE_CONFIRM   
6    3000002  1488949064945887091        NaN      IOC                   NaN   
7    3000003  1488949109654115659        NaN      IOC                   NaN   
8    3000003  1488949109654294973          1      NaN     NEW_ORDER_CONFIRM   
9    3000003  1488949109654299930      16388      NaN  CANCEL_ORDER_CONFIRM  

使用@jezrael解决方案制作的功能

>>> def f(x):
...     #print (x)
...     #check if NEW_CONFIRM and IOC in group
...     if  ((x.ResponseType == 'NEW_ORDER_CONFIRM').any() and (x.Duration == 'IOC').any()):
...         #filter data - output scalar
...         a = x.loc[x.Duration == 'IOC', ['TimeStamp','Duration']]
...         print(a)
...         a1 = str(a['TimeStamp'].item())
...         a2 = a['Duration'].item()
...         b = x.loc[x.Response == 'NEW_ORDER_CONFIRM', 'ErrorCode'].item()
...         c = x.loc[x.Response.str.isin(['TRADE_CONFIRM', 'CANCEL_ORDER_CONFIRM']), 'ResponseType'].item()
...         #return series with index for align data
...         return pd.Series([a1, a2, b, c], index=df.columns[1:])
... 
>>> df2 = df.groupby('ErrorCode').apply(f).dropna(how='all').reset_index()
>>> df2
Empty DataFrame
Columns: [index]
Index: []

预期的操作

OrderID, TimeStamp,ErrorCode,Duration,ResponseType
3000000,1488948188555841641,0,IOC,TRADE_CONFIRM
3000001,1488948658787676012,1,IOC,TRADE_CONFIRM
3000003,1488949109654115659,1,IOC,CANCEL_ORDER_CONFIRM

1 个答案:

答案 0 :(得分:2)

我认为你需要:

def f(x):
    #print (x)
    #check if NEW_CONFIRM and IOC in group
    if  ((x.Response == 'NEW_CONFIRM').any() and (x.Duration == 'IOC').any()):
        #filter data - output scalar
        a = x.loc[x.Duration == 'IOC', ['Time','Duration']]
        a1 = str(a['Time'].item())
        a2 = a['Duration'].item()
        b = x.loc[x.Response == 'NEW_CONFIRM', 'Path'].item()
        c = x.loc[x.Response.str.contains('TRADED'), 'Response'].item()
        #return series with index for align data
        return pd.Series([a1, a2, b, c], index=df.columns[1:])

#apply function anr remove NaN rows
df = df.groupby('Token').apply(f).dropna(how='all').reset_index()
print (df)
   Token    Time Path Duration    Response
0      1  142830  IOC        0      TRADED
1      2  142830  IOC        0  NOT_TRADED

编辑:

列名中只有一些拼写错误:

def f(x):
    #print (x)
    #check if NEW_CONFIRM and IOC in group
    if  ((x.ResponseType == 'NEW_ORDER_CONFIRM').any() and (x.Duration == 'IOC').any()):
        #filter data - output scalar
        a = x.loc[x.Duration == 'IOC', ['TimeStamp','Duration']]
        a1 = str(a['TimeStamp'].item())
        a2 = a['Duration'].item()
        b = x.loc[x.ResponseType == 'NEW_ORDER_CONFIRM', 'ErrorCode'].item()
        c = x.loc[x.ResponseType.isin(['TRADE_CONFIRM', 'CANCEL_ORDER_CONFIRM']), 'ResponseType'].item()
        #return series with index for align data
        return pd.Series([a1, a2, b, c], index=df.columns[1:])

#apply function anr remove NaN rows
df = df.groupby('OrderID').apply(f).dropna(how='all').reset_index()
print (df)
   OrderID            TimeStamp ErrorCode  Duration          ResponseType
0  3000000  1488948188555841641       IOC       0.0         TRADE_CONFIRM
1  3000001  1488948658787676012       IOC       1.0         TRADE_CONFIRM
2  3000003  1488949109654115659       IOC       1.0  CANCEL_ORDER_CONFIRM

编辑:

用于测试数据长度:

def f(x):
    #print (x)
    #check if NEW_CONFIRM and IOC in group
    if  ((x.ResponseType == 'NEW_ORDER_CONFIRM').any() and (x.Duration == 'IOC').any()):
        #filter data - output scalar
        a = x.loc[x.Duration == 'IOC', ['TimeStamp','Duration']]
        a1 = str(a['TimeStamp'].item())
        a2 = a['Duration'].item()
        b = x.loc[x.ResponseType == 'NEW_ORDER_CONFIRM', 'ErrorCode'].item()
        c = x.loc[x.ResponseType.isin(['TRADE_CONFIRM', 'CANCEL_ORDER_CONFIRM']), 'ResponseType'].item()
        #return series with index for align data
        if len(a) > 1:
            print (a['TimeStamp'])
        if len(x.loc[x.ResponseType == 'NEW_ORDER_CONFIRM', 'ErrorCode']) > 1:
            print (x.loc[x.ResponseType == 'NEW_ORDER_CONFIRM', 'ErrorCode'])
        if len(x.loc[x.ResponseType.isin(['TRADE_CONFIRM', 'CANCEL_ORDER_CONFIRM']), 'ResponseType']) > 1:
            print (x.loc[x.ResponseType.isin(['TRADE_CONFIRM', 'CANCEL_ORDER_CONFIRM']), 'ResponseType'])
        return pd.Series([a1, a2, b, c], index=df.columns[1:])

#apply function anr remove NaN rows
df = df.groupby('OrderID').apply(f).dropna(how='all').reset_index()
print (df)