通过多列选择

时间:2015-03-13 23:02:20

标签: python python-3.x pandas

我打算根据值的组合将某些pandas数据帧删除到两列中。

假设我的数据框看起来像

        date  PX_LAST  CONTRACT_VALUE GEN_TICKER
1       19860401  92.6600       231650.00      EDM87
2       19860401  92.5100       231275.00      EDU87
3       19860401  92.3700       230925.00      EDZ87
4       19860401  92.2500       230625.00      EDH88
6       19860402  92.6700       231675.00      EDM87
7       19860402  92.5200       231300.00      EDU87
8       19860402  92.3700       230925.00      EDZ87
9       19860402  92.2400       230600.00      EDH88
11      19860403  92.6200       231550.00      EDM87
12      19860403  92.4700       231175.00      EDU87
13      19860403  92.3200       230800.00      EDZ87
14      19860403  92.1900       230475.00      EDH88
16      19860404  92.6900       231725.00      EDM87
17      19860404  92.5300       231325.00      EDU87
18      19860404  92.3800       230950.00      EDZ87
         ...      ...             ...        ...
241801  20150206  99.7200       249300.00      EDH15
241841  20150209  99.7200       249300.00      EDH15
241881  20150210  99.7200       249300.00      EDH15
241921  20150211  99.7200       249300.00      EDH15
241961  20150212  99.7200       249300.00      EDH15
242001  20150213  99.7200       249300.00      EDH15
242041  20150217  99.7200       249300.00      EDH15
242081  20150218  99.7225       249306.24      EDH15
242121  20150219  99.7225       249306.24      EDH15
242161  20150220  99.7200       249300.00      EDH15
242201  20150223  99.7225       249306.24      EDH15
242241  20150224  99.7325       249331.25      EDH15
242281  20150225  99.7350       249337.50      EDH15
242321  20150226  99.7350       249337.50      EDH15
242361  20150227  99.7350       249337.50      EDH15

[193411 rows x 4 columns]

然后让

i = 'EDM87'
j = 19870412

我想从数据框中排除那些包含GEN_TICKER == idate < j

的行

我的代码如下所示:

x2 = [~(xi & xj) for xi, xj in zip((fdata['GEN_TICKER'] == i).tolist(),
                                   (fdata['date'].tolist() < j).tolist())]
fdata = fdata[x2]

它完成了这项工作,但它看起来并不高效。有一个更好的方法吗?或者,是否有任何inplace方法可以删除行(这样我就可以避免将上面的fdata重新分配给简化的数据帧)?

我尝试fdata.loc[:,fdata.loc['GEN_TICKER']==i],但收到错误:KeyError: 'the label [GEN_TICKER] is not in the [index]'

我尝试了fdata.loc[:,(fdata.loc['GEN_TICKER']==i).tolist()],但得到了同样的错误。当GEN_TICKER是列名时,为什么会出现此错误?

具有相同错误的其他变体为fdata.loc[fdata.loc['GEN_TICKER']==i]fdata.loc[fdata.loc['GEN_TICKER']==i,:]

我尝试了fdata[fdata['GEN_TICKER']==i & fdata['date'>j]]并收到了另一种类型的错误:TypeError: cannot compare a dtyped [float64] array with a scalar of type [bool] - 但单独的fdata[fdata['GEN_TICKER']==i]fdata[fdata['date'>j]]都有效。

我使用的是Python 3和Pandas 0.15。

由于

1 个答案:

答案 0 :(得分:2)

你非常接近。稍微更改j以便我们可以看到效果,即使我们只查看前几行:

>>> i = 'EDM87'
>>> j = 19860403
>>> df[~((df.GEN_TICKER == i) & (df.date < j))]
        date  PX_LAST  CONTRACT_VALUE GEN_TICKER
2   19860401    92.51          231275      EDU87
3   19860401    92.37          230925      EDZ87
4   19860401    92.25          230625      EDH88
7   19860402    92.52          231300      EDU87
8   19860402    92.37          230925      EDZ87
9   19860402    92.24          230600      EDH88
11  19860403    92.62          231550      EDM87
12  19860403    92.47          231175      EDU87
13  19860403    92.32          230800      EDZ87
14  19860403    92.19          230475      EDH88
16  19860404    92.69          231725      EDM87
17  19860404    92.53          231325      EDU87
18  19860404    92.38          230950      EDZ87

您基本上只需要添加括号。 (我还添加了NOT运算符~,以便我们保留那些未被删除的运算符。)