Pandas 数据框中值的矢量化查找

Posted

技术标签:

【中文标题】Pandas 数据框中值的矢量化查找【英文标题】:Vectorized look-up of values in Pandas dataframe 【发布时间】:2012-12-03 07:31:06 【问题描述】:

我有两个 pandas 数据框,一个称为“订单”,另一个称为“daily_prices”。 daily_prices 如下:

              AAPL    GOOG     IBM    XOM
2011-01-10  339.44  614.21  142.78  71.57
2011-01-13  342.64  616.69  143.92  73.08
2011-01-26  340.82  616.50  155.74  75.89
2011-02-02  341.29  612.00  157.93  79.46
2011-02-10  351.42  616.44  159.32  79.68
2011-03-03  356.40  609.56  158.73  82.19
2011-05-03  345.14  533.89  167.84  82.00
2011-06-03  340.42  523.08  160.97  78.19
2011-06-10  323.03  509.51  159.14  76.84
2011-08-01  393.26  606.77  176.28  76.67
2011-12-20  392.46  630.37  184.14  79.97

订单如下:

           direction  size ticker  prices
2011-01-10       Buy  1500   AAPL  339.44
2011-01-13      Sell  1500   AAPL  342.64
2011-01-13       Buy  4000    IBM  143.92
2011-01-26       Buy  1000   GOOG  616.50
2011-02-02      Sell  4000    XOM   79.46
2011-02-10       Buy  4000    XOM   79.68
2011-03-03      Sell  1000   GOOG  609.56
2011-03-03      Sell  2200    IBM  158.73
2011-06-03      Sell  3300    IBM  160.97
2011-05-03       Buy  1500    IBM  167.84
2011-06-10       Buy  1200   AAPL  323.03
2011-08-01       Buy    55   GOOG  606.77
2011-08-01      Sell    55   GOOG  606.77
2011-12-20      Sell  1200   AAPL  392.46

两个数据框的索引都是 datetime.date。 “订单”数据框中的“价格”列是通过使用列表推导循环遍历所有订单并在“每日价格”数据框中查找特定日期的特定代码,然后将该列表作为一列添加到“订单”数据框。我想使用数组操作而不是循环的东西来做到这一点。可以吗?我尝试使用:

daily_prices.ix[日期,代码]

但这会返回两个列表的笛卡尔积矩阵。我希望它返回仅包含指定日期的指定代码价格的列向量。

【问题讨论】:

【参考方案1】:

使用我们的朋友lookup,专为此目的而设计:

In [17]: prices
Out[17]: 
              AAPL    GOOG     IBM    XOM
2011-01-10  339.44  614.21  142.78  71.57
2011-01-13  342.64  616.69  143.92  73.08
2011-01-26  340.82  616.50  155.74  75.89
2011-02-02  341.29  612.00  157.93  79.46
2011-02-10  351.42  616.44  159.32  79.68
2011-03-03  356.40  609.56  158.73  82.19
2011-05-03  345.14  533.89  167.84  82.00
2011-06-03  340.42  523.08  160.97  78.19
2011-06-10  323.03  509.51  159.14  76.84
2011-08-01  393.26  606.77  176.28  76.67
2011-12-20  392.46  630.37  184.14  79.97

In [18]: orders
Out[18]: 
                  Date direction  size ticker  prices
0  2011-01-10 00:00:00       Buy  1500   AAPL  339.44
1  2011-01-13 00:00:00      Sell  1500   AAPL  342.64
2  2011-01-13 00:00:00       Buy  4000    IBM  143.92
3  2011-01-26 00:00:00       Buy  1000   GOOG  616.50
4  2011-02-02 00:00:00      Sell  4000    XOM   79.46
5  2011-02-10 00:00:00       Buy  4000    XOM   79.68
6  2011-03-03 00:00:00      Sell  1000   GOOG  609.56
7  2011-03-03 00:00:00      Sell  2200    IBM  158.73
8  2011-06-03 00:00:00      Sell  3300    IBM  160.97
9  2011-05-03 00:00:00       Buy  1500    IBM  167.84
10 2011-06-10 00:00:00       Buy  1200   AAPL  323.03
11 2011-08-01 00:00:00       Buy    55   GOOG  606.77
12 2011-08-01 00:00:00      Sell    55   GOOG  606.77
13 2011-12-20 00:00:00      Sell  1200   AAPL  392.46

In [19]: prices.lookup(orders.Date, orders.ticker)
Out[19]: 
array([ 339.44,  342.64,  143.92,  616.5 ,   79.46,   79.68,  609.56,
        158.73,  160.97,  167.84,  323.03,  606.77,  606.77,  392.46])

【讨论】:

我自己尝试了各种花哨的方法我应该知道你已经实现了它。感谢这个很棒的包裹 Wes。让生活变得如此轻松。迫不及待地想看看你接下来会想出什么。 当将DateTime 用于ordersprices 数据帧作为索引时,我得到“TypeError: object of type 'datetime.datetime' has no len()”不同的代码:myval = prices.lookup(order[0], order[1]) 其中order 来自for order in orders。因此,在我的情况下,订单将是 1d 而不是 2d,如您上面的示例(订单)。是错误的用法还是如何修复? (我想从具有该信息的价格数据框中获取单个日期和股票代码(订单数据框外)的匹配条目。) 我不确定这是否会在这里引起注意,但首先在这里尝试是有意义的:我想做一些接近的事情,但我需要将一个系列值与按天索引的系列匹配按日期时间索引的数据框。我得到“系列对象没有属性查找”。所以像 df['d'] = df.index.date -> df['x'] = ts.lookup(df.d)

以上是关于Pandas 数据框中值的矢量化查找的主要内容,如果未能解决你的问题,请参考以下文章

vectorize向量化函数对DataFrame中值进行复杂运算

为 Scikit-Learn 向量化 Pandas 数据框

在 pandas 中对函数进行矢量化

Pandas:向量化局部范围操作([i:i+2] 行的最大值和总和)

矢量化循环熊猫

在 pandas 数据框中插入 sklearn CountVectorizer 的结果