值与一组值的矢量化比较

2024-06-26 13:36:36 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个pd.Dataframe,该列包含一个值,如

df.iloc[:10]['occ']
Out[18]: 
0    4220
1     205
2    7630
3    8965
4     430
5    3930
6    4230
7    5620
8    4040
9    4130

然后,我有另一个数据帧,其值为start和{},分别用于不同的组。我想根据组的occ值将组分配给第一个数据帧。在

^{pr2}$

由于这些群不相交,我们有一个简单的双射。我计划为每个occ值取最后一行的组索引,该索引小于所述的occ值。在

testAgainst = np.repeat(dfGroups['start'].values[np.newaxis, :], repeats=10, axis=0)

array([[  10, 1000, 3600, 3700, 4000, 4200, 4300, 4700, 5000, 6000, 6200,
        7000, 7700, 9000],
       [  10, 1000, 3600, 3700, 4000, 4200, 4300, 4700, 5000, 6000, 6200,
        7000, 7700, 9000],
       [  10, 1000, 3600, 3700, 4000, 4200, 4300, 4700, 5000, 6000, 6200,
        7000, 7700, 9000],
       [  10, 1000, 3600, 3700, 4000, 4200, 4300, 4700, 5000, 6000, 6200,
        7000, 7700, 9000],
       [  10, 1000, 3600, 3700, 4000, 4200, 4300, 4700, 5000, 6000, 6200,
        7000, 7700, 9000],
       [  10, 1000, 3600, 3700, 4000, 4200, 4300, 4700, 5000, 6000, 6200,
        7000, 7700, 9000],
       [  10, 1000, 3600, 3700, 4000, 4200, 4300, 4700, 5000, 6000, 6200,
        7000, 7700, 9000],
       [  10, 1000, 3600, 3700, 4000, 4200, 4300, 4700, 5000, 6000, 6200,
        7000, 7700, 9000],
       [  10, 1000, 3600, 3700, 4000, 4200, 4300, 4700, 5000, 6000, 6200,
        7000, 7700, 9000],
       [  10, 1000, 3600, 3700, 4000, 4200, 4300, 4700, 5000, 6000, 6200,
        7000, 7700, 9000]])

现在,既然维度是(10,)和{},那么就应该有自动广播了。我希望能做到

df.iloc[:10]['occ'] < testAgainst

结果呢

0  False False False False False False True  True  True  True  True  True  True  True 
1  False True  True  True  True  True  True  True  True  True  True  True  True  True 

对于前两行,因为4220大于4200(以及其后的所有数字),而{}大于{}。在

但是,我知道

Traceback (most recent call last):
  File "/home/foo/.conda/envs/myenv3/lib/python3.5/site-packages/IPython/core/interactiveshell.py", line 2881, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-28-1bce7761846c>", line 1, in <module>
    df.iloc[:10]['occ'] < testAgainst
  File "/home/foo/.conda/envs/myenv3/lib/python3.5/site-packages/pandas/core/ops.py", line 832, in wrapper
    return self._constructor(na_op(self.values, np.asarray(other)),
  File "/home/foo/.conda/envs/myenv3/lib/python3.5/site-packages/pandas/core/ops.py", line 792, in na_op
    result = getattr(x, name)(y)
ValueError: operands could not be broadcast together with shapes (10,) (10,14) 
  1. 为什么这里的广播不起作用?在
  2. {在这种情况下,{1千5百万行在这个框架中是最有效的。在

Tags: inselffalsetruedfhomefoonp
1条回答
网友
1楼 · 发布于 2024-06-26 13:36:36

1)广播失败的原因是Series对象形成一个一维标记数组[shape=(10,)],这与二维数组[shape=(1, 14)]相比。在

让我们考虑一下:ser = df.iloc[:10]['occ']

如果你做了:

>>> ser.iloc[0] < testAgainst
array([[False, False, False, False, False, False,  True,  True,  True,
     True,  True,  True,  True,  True]], dtype=bool)

这意味着,如果您可以将相同的比较应用于序列的所有行,它将给出正确的结果。在

^{pr2}$

但是,这是非常缓慢的,因为它没有矢量化,因此不可能将其应用于大量的行。在

现在您可以做的是重塑序列,以便在其中插入额外的维度。在

这允许NumPy分别匹配序列(10, 1)和数组{}的两个形状,以便通过在各自的维度中配对来比较它们。在

2)更好的解决方案可以是:

>>> pd.Series((ser.values[:, None] < testAgainst).tolist())   # same as ser.values.reshape(-1,1)

结果输出:

0    [False, False, False, False, False, False, Tru...
1    [False, True, True, True, True, True, True, Tr...
2    [False, False, False, False, False, False, Fal...
3    [False, False, False, False, False, False, Fal...
4    [False, True, True, True, True, True, True, Tr...
5    [False, False, False, False, True, True, True,...
6    [False, False, False, False, False, False, Tru...
7    [False, False, False, False, False, False, Fal...
8    [False, False, False, False, False, True, True...
9    [False, False, False, False, False, True, True...
dtype: object

注意:测试数组的一个样本就足够了,您不需要重复这个数组来匹配series对象的形状。在

相关问题 更多 >