Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/289.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 有没有按功能划分的numpy组?_Python_Arrays_Numpy - Fatal编程技术网

Python 有没有按功能划分的numpy组?

Python 有没有按功能划分的numpy组?,python,arrays,numpy,Python,Arrays,Numpy,numpy中是否有任何函数可以将此数组按第一列向下分组 我在网上找不到好答案 >>> a array([[ 1, 275], [ 1, 441], [ 1, 494], [ 1, 593], [ 2, 679], [ 2, 533], [ 2, 686], [ 3, 559], [ 3, 219], [ 3, 455],

numpy中是否有任何函数可以将此数组按第一列向下分组

我在网上找不到好答案

>>> a
array([[  1, 275],
       [  1, 441],
       [  1, 494],
       [  1, 593],
       [  2, 679],
       [  2, 533],
       [  2, 686],
       [  3, 559],
       [  3, 219],
       [  3, 455],
       [  4, 605],
       [  4, 468],
       [  4, 692],
       [  4, 613]])
想要的输出:

array([[[275, 441, 494, 593]],
       [[679, 533, 686]],
       [[559, 219, 455]],
       [[605, 468, 692, 613]]], dtype=object)
产出:

array([[275, 441, 494, 593], [679, 533, 686], [559, 219, 455],
       [605, 468, 692, 613]], dtype=object)
该软件包(免责声明:我是它的作者)旨在填补numpy的这一空白。numpy索引中的所有操作都是完全矢量化的,在创建此库的过程中没有O(n^2)算法受到损害

import numpy_indexed as npi
npi.group_by(a[:, 0]).split(a[:, 1])
请注意,通常更有效的方法是直接计算这些组的相关属性(即,group_by(keys).mean(value)),而不是首先拆分为一个列表/锯齿数组。

受其启发,但没有他的库,并使用数组的第一列总是在增加的事实(如果不是,则首先使用
a=a[a]进行排序)[:,0].argsort()]

我没有“计时”,但这可能是解决问题的更快方法:

  • 没有python本机循环
  • 结果列表是numpy数组,如果您需要对其执行其他numpy操作,则不需要进行新的转换
  • 类似O(n)的复杂性
[编辑]多亏了 (cf comment)

我使用了np.unique()后跟np.extract()


[array([275,441,494,593])、array([679,533,686])、array([559,219,455])、array([605,468,692,613])]
Numpy在这里不是很方便,因为所需的输出不是整数数组(它是列表对象的数组)

我建议使用纯Python的方式

from collections import defaultdict

%%timeit
d = defaultdict(list)
for key, val in a:
    d[key].append(val)
10.7 µs ± 156 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

# result:
defaultdict(list,
        {1: [275, 441, 494, 593],
         2: [679, 533, 686],
         3: [559, 219, 455],
         4: [605, 468, 692, 613]})
…或者说:

import pandas as pd

%%timeit
df = pd.DataFrame(a, columns=["key", "val"])
df.groupby("key").val.apply(pd.Series.tolist)
979 µs ± 3.3 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

# result:
key
1    [275, 441, 494, 593]
2         [679, 533, 686]
3         [559, 219, 455]
4    [605, 468, 692, 613]
Name: val, dtype: object
简化并考虑HS星云的注释,可以使用
return\u index=True
而不是
return\u counts=True
,并去掉
cumsum

np.split(a[:,1], np.unique(a[:,0], return_index = True)[1])[1:]
输出

[array([275, 441, 494, 593]),
 array([679, 533, 686]),
 array([559, 219, 455]),
 array([605, 468, 692, 613])]

给定X作为要分组的项目数组,y(1D数组)作为相应的组,以下函数使用numpy进行分组:

因此,
groupby(a[:,1],a[:,0])
返回
[array([275,441,494,593]),array([679,533,686]),array([559,219,455]),array([605,468,692,613])
我们可能会发现生成
dict也很有用:

def groupby(X): 
    X = np.asarray(X) 
    x_uniques = np.unique(X) 
    return {xi:X[X==xi] for xi in x_uniques} 
让我们试一下:

X=[1,1,2,2,3,3,3,3,4,5,6,7,7,8,9,9,1,1,1]
groupby(X)                                                                                                      
Out[9]: 
{1: array([1, 1, 1, 1, 1]),
 2: array([2, 2]),
 3: array([3, 3, 3, 3]),
 4: array([4]),
 5: array([5]),
 6: array([6]),
 7: array([7, 7]),
 8: array([8]),
 9: array([9, 9])}

请注意,这本身并不是非常引人注目的-但是如果我们将
X
作为
对象或
命名为tuple
,然后提供一个
groupby
函数,它会变得更有趣。稍后会将其放进去。

晚到派对上,但无论如何。如果您不仅计划对数组进行分组,而且还想对它们进行操作像是求和、均值等等,而且你这样做的速度很快,你也可能需要考虑。所有这些组操作都被优化了,并且用NUBA来实现。它们很容易胜过其他提到的解决方案。

from numpy\u groupies.aggregate\u numpy import aggregate
聚合(a[:,0],a[:,1],“数组”,填充值=[])
>>>数组([array([],dtype=int64),数组([275441494593]),
数组([679533686]),数组([559219455]),
数组([605468692613]),数据类型=对象)
合计(a[:,0],a[:,1],“总和”)
>>>数组([018031898123378])

要得到完全相同的答案,因为他希望
数组([[x]代表x在[list(a[a[:,0]==i,1])代表i在n]])
注意这个解决方案需要O(n^2)操作,这使得它非常低效。使用
np.unique
而不是
unique
来清除你的代码。工作得很好。尽管我不明白“1”是什么意思在
列表中扮演角色(a[a[:,0]==i,1])
statement@partizanos,因为第1栏中的项目应该分组。谢谢。我的意思是,使用On2算法本质上是痛苦的,即使对所说的算法本身也是如此。但是,是的,我想你必须假设On2算法也自我意识到它的劣势,这句话才有意义(n^2)
算法受到了伤害“。你为什么要对他们“友好”呢?相反,你要伤害他们:强迫他们“变得更瘦”如果第一列没有排序怎么办?我们可以将排序与创建组结合起来吗?@Vidak
a.sort(axis=0)
会按第一列对数组进行排序(假设索引存储在那里)@ns63sr什么是
idx
?此答案不会产生正确的输出。如果您设置
idx=a[:,0]
,使完整代码
np.split(a[:,1],np.unique(a[:,0],return_index=True)[1:]
很好的解决方案,但它有一个限制。如果缺少索引,这就不起作用(比如2)。它只会返回一个3项长的列表,但由于缺少一些索引,您将无法通过索引访问新列表。有没有办法为不存在的索引返回一个空列表?
pandas
performance hit有点残酷。不知道
datatable
是否可以得到这个很好的答案。而且很容易记住r!好吧,第二个可能没那么多。这又增加了我的技巧。你基于一列对2d数组进行排序的方法不正确。请使用
a=a[a.T[0,:].argsort()]
instead.true!这种排序是在第二列中进行的。我编辑了答案。谢谢当您使用numpy时,返回python dicts通常会大大降低速度。如果您使用较大的数组,请坚持使用numpy功能。当然-但通常足够多的任务都是“小数据”.如果任务比@vincentj的答案更大——我已经投票并发表了评论——效果会更好。但这并不完全是言外之意
[array([275, 441, 494, 593]),
 array([679, 533, 686]),
 array([559, 219, 455]),
 array([605, 468, 692, 613])]
def groupby(X, y):
    y = np.asarray(y)
    X = np.asarray(X)
    y_uniques = np.unique(y)
    return [X[y==yi] for yi in y_uniques]
def groupby(X): 
    X = np.asarray(X) 
    x_uniques = np.unique(X) 
    return {xi:X[X==xi] for xi in x_uniques} 
X=[1,1,2,2,3,3,3,3,4,5,6,7,7,8,9,9,1,1,1]
groupby(X)                                                                                                      
Out[9]: 
{1: array([1, 1, 1, 1, 1]),
 2: array([2, 2]),
 3: array([3, 3, 3, 3]),
 4: array([4]),
 5: array([5]),
 6: array([6]),
 7: array([7, 7]),
 8: array([8]),
 9: array([9, 9])}