我有几个numpy数组;我想构建一个groupby方法,该方法将具有这些数组的组id。它将允许我在组id上索引这些数组,以便对组执行操作。你知道吗
例如:
import numpy as np
import pandas as pd
a = np.array([1,1,1,2,2,3])
b = np.array([1,2,2,2,3,3])
def group_np(groupcols):
groupby = np.array([''.join([str(b) for b in bs]) for bs in zip(*[c for c in groupcols])])
_, groupby = np.unique(groupby, return_invesrse=True)
return groupby
def group_pd(groupcols):
df = pd.DataFrame(groupcols[0])
for i in range(1, len(groupcols)):
df[i] = groupcols[i]
for i in range(len(groupcols)):
df[i] = df[i].fillna(-1)
return df.groupby(list(range(len(groupcols)))).grouper.group_info[0]
输出:
group_np([a,b]) -> [0, 1, 1, 2, 3, 4]
group_pd([a,b]) -> [0, 1, 1, 2, 3, 4]
有没有更有效的方法来实现它,最好是在纯numpy中?目前的瓶颈似乎是构建一个向量,该向量对每个组都有唯一的值—目前我正在通过将每个向量的值串联为字符串来实现这一点。你知道吗
我想让它适用于任何数量的输入向量,它可以有数百万个元素。你知道吗
编辑:下面是另一个测试用例:
a = np.array([1,2,1,1,1,2,3,1])
b = np.array([1,2,2,2,2,3,3,2])
在这里,组元素2、3、4、7应该是相同的。你知道吗
编辑2:添加一些基准。你知道吗
a = np.random.randint(1, 1000, 30000000)
b = np.random.randint(1, 1000, 30000000)
c = np.random.randint(1, 1000, 30000000)
def group_np2(groupcols):
_, groupby = np.unique(np.stack(groupcols), return_inverse=True, axis=1)
return groupby
%timeit group_np2([a,b,c])
# 25.1 s +/- 1.06 s per loop (mean +/- std. dev. of 7 runs, 1 loop each)
%timeit group_pd([a,b,c])
# 21.7 s +/- 646 ms per loop (mean +/- std. dev. of 7 runs, 1 loop each)
在数组} 中将参数
a
和b
上使用np.stack
之后,如果在^{return_inverse
设置为True
,则您要查找的是输出:您可以用所有向量的列表来替换
[a,b]
中的np.stack
。你知道吗编辑:一个更快的解决方案是在数组的
sum
上使用np.unique
乘以max
的累积积(np.cumprod
)加上groupcols
中所有先前数组的1。例如:要检查:
注意:与每个组相关联的数字可能不相同(这里我将
a
的第一个元素改为3)但群体本身是一样的。你知道吗
现在检查时间:
numpy_indexed包(dsiclaimer:I am its authos)涵盖了以下类型的用例:
像这样传递索引数组的元组可以避免创建副本;但是如果不介意创建副本,也可以使用堆栈:
相关问题 更多 >
编程相关推荐