【问题标题】:compare column values of dataframes with non-unique indices of different length将数据帧的列值与不同长度的非唯一索引进行比较
【发布时间】:2014-07-09 16:23:45
【问题描述】:

我有两个如下所示的数据框:

dataOB = pd.DataFrame({'Time': \
                 [dt.datetime(2013,4,17,9,0,1), \
                  dt.datetime(2013,4,17,9,0,1), \
                  dt.datetime(2013,4,17,9,0,2), \
                  dt.datetime(2013,4,17,9,0,2), \
                  dt.datetime(2013,4,17,9,0,2), \
                  dt.datetime(2013,4,17,9,0,2), \
                  dt.datetime(2013,4,17,9,0,3), \
                  dt.datetime(2013,4,17,9,0,3)], \
                 'hsec': [2,54,0,42,60,89,0,10], 'val': [4,5,5,3,2,4,4,7]})

dfEq = pd.DataFrame({'Time': [dt.datetime(2013,4,17,9,0,1), \
                          dt.datetime(2013,4,17,9,0,1), \
                          dt.datetime(2013,4,17,9,0,1), \
                          dt.datetime(2013,4,17,9,0,2), \
                          dt.datetime(2013,4,17,9,0,2), \
                          dt.datetime(2013,4,17,9,0,3), \
                          dt.datetime(2013,4,17,9,0,3), \
                          dt.datetime(2013,4,17,9,0,3), \
                          dt.datetime(2013,4,17,9,0,3)], \
                 'price': [4,4,5,3,3,4,5,4,5], \
                 'flag': ['K','V','V','V','K','K','V','K','V']})

我需要为 dfEq 中的每一行分配一个值,该值取决于该行中的价格是否存在于同一时间戳的 dataOB 中的“val”值中。

我的第一个解决方案如下所示,并给了我想要的结果。 (下面是“但是”。)

dataOB.set_index('Time', inplace=True)
dfEq.set_index('Time', inplace=True)

dfEq['type'] = np.zeros(len(dfEq.index))

tmpOB = pd.DataFrame([dataOB.ix[trTime,'val'] for trTime in dfEq.index], \
index = dfEq.index)
>>> tmpOB
                     0  1   2   3
Time                             
2013-04-17 09:00:01  4  5 NaN NaN
2013-04-17 09:00:01  4  5 NaN NaN
2013-04-17 09:00:01  4  5 NaN NaN
2013-04-17 09:00:02  5  3   2   4
2013-04-17 09:00:02  5  3   2   4
2013-04-17 09:00:03  4  7 NaN NaN
2013-04-17 09:00:03  4  7 NaN NaN
2013-04-17 09:00:03  4  7 NaN NaN
2013-04-17 09:00:03  4  7 NaN NaN

[9 rows x 4 columns]

dfEq.type[tmpOB.eq(dfEq.price,axis=0).any(axis=1) & (dfEq.flag=='K')] = 'MBO'
dfEq.type[tmpOB.eq(dfEq.price,axis=0).any(axis=1) & (dfEq.flag=='V')] = 'LSO'

>>> dfEq
                     price  flag type
Time                                 
2013-04-17 09:00:01      4     K  MBO
2013-04-17 09:00:01      4     V  LSO
2013-04-17 09:00:01      5     V  LSO
2013-04-17 09:00:02      3     V  LSO
2013-04-17 09:00:02      3     K  MBO
2013-04-17 09:00:03      4     K  MBO
2013-04-17 09:00:03      5     V    0
2013-04-17 09:00:03      4     K  MBO
2013-04-17 09:00:03      5     V    0

[9 rows x 3 columns]

这里的问题是我有很多这样的数据帧,而且它们都相当大,因此由于列表理解,从内存和计算时间的两个方面来看,tmpOB 的创建都不可行。

所以我的问题是:有没有一种方法可以在不需要列表理解或循环的情况下获得相同的结果?也许有一种更直接的方法可以将每一行的价格与“val”中的同时代元素进行比较?

(我也尝试使用 pd.merge() (在两个数据帧中设置索引之前)像

mergedDf = pd.merge(dfEq,dataOB,on='Time')

mergedDf['type'] = np.zeros(len(mergedDf.index))

mergedDf.type[(mergedDf.price==mergedDf.val) & \
              (mergedDf.flag=='K')] = 'MBO'
mergedDf.type[(mergedDf.price==mergedDf.val) & \
              (mergedDf.flag=='V')] = 'LSO'

但是我不知道如何再次摆脱不必要的行。)

【问题讨论】:

    标签: python pandas indexing


    【解决方案1】:

    我发现我可以使用 pandas 的 unstack() 来创建没有循环的 tmpOB,这使得代码更快。

    首先我必须通过多索引来索引 dataOB 来获取

                              val
    Time                hsec     
    2013-04-17 09:00:01 0       4
                        1       5
    2013-04-17 09:00:02 0       5
                        1       3  
                        2       2
                        3       4
    2013-04-17 09:00:03 0       4
                        1       7
    

    (将 'hsec' 级索引放入此表单需要一些操作,请参阅 pandas - change values of second level index to display position within first level index

    那么,通过

    得到tmpOB
    dataOB.unstack('hsec') 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-17
      • 1970-01-01
      • 2021-10-03
      • 2016-01-22
      • 2020-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多