基于数组的另一列(Python)对一列中的最小-最大值进行聚集
如果这些值具有相同的索引,我将尝试连接它们。我正在使用矩形,因此我知道:基于数组的另一列(Python)对一列中的最小-最大值进行聚集,python,python-3.x,numpy,Python,Python 3.x,Numpy,如果这些值具有相同的索引,我将尝试连接它们。我正在使用矩形,因此我知道: 始终至少有两个相同的索引 如果有两个以上的索引,我只需要存储最大值和最小值 基本上 发件人: a = array([ [ 1, 5], [ 1, 7], [ 2, 8], [ 2, 10], [ 2, 22], [ 3, 55], [ 3, 77]]) 致: 我曾尝试将其转换为一个列表,并使用for循环遍历每个值,
- 始终至少有两个相同的索引
- 如果有两个以上的索引,我只需要存储最大值和最小值
a = array([
[ 1, 5],
[ 1, 7],
[ 2, 8],
[ 2, 10],
[ 2, 22],
[ 3, 55],
[ 3, 77]])
致:
我曾尝试将其转换为一个列表,并使用for循环遍历每个值,但这需要相当长的时间
我也尝试过对数组进行排序,np.sort(a,axis=0)
并每隔一行进行一次排序,但由于索引可能不止两个,所以失败了
我对numpy还不熟悉,所以不知道还能尝试什么
任何建议都会有帮助,谢谢
编辑:其行为类似于字典,其中键为[0],值为[1:]
如果有两个以上的值,我只保留最小值和最大值。使用
pandas
import pandas as pd
# create a dataframe with 2 columns corresponding to the columns of a
df = pd.DataFrame({ 'indices':a[:,0],'values':a[:,1]})
# compute min and max by indices
df2 = df.groupby('indices').agg({'values': ['min', 'max']}).reset_index()
# convert to numpy array
np.asarray(df2)
#array([[ 1, 5, 7],
# [ 2, 8, 22],
# [ 3, 55, 77]], dtype=int64)
使用
pandas
import pandas as pd
# create a dataframe with 2 columns corresponding to the columns of a
df = pd.DataFrame({ 'indices':a[:,0],'values':a[:,1]})
# compute min and max by indices
df2 = df.groupby('indices').agg({'values': ['min', 'max']}).reset_index()
# convert to numpy array
np.asarray(df2)
#array([[ 1, 5, 7],
# [ 2, 8, 22],
# [ 3, 55, 77]], dtype=int64)
用numpy做这件事的一种方式, 可以使用numpy.split根据第一个轴中的值将它们拆分为单独的数组。然后你可以找到最小值和最大值 有关拆分及其工作原理的详细信息, 你可以看看答案。我在这里不再重复同样的内容
ar = np.split(a, np.flatnonzero(a[1:,0] != a[:-1,0])+1,axis=0)
上面的行拆分并为轴0中的每个唯一值生成数组列表
上述行将产生如下输出:
[
array([[1, 5],
[1, 7]]),
array([[ 2, 8],
[ 2, 10],
[ 2, 22]]),
array([[ 3, 55],
[ 3, 77]])
]
然后您可以迭代它们,以找到输出中所期望的列表的性质
final_list = []
for i in ar:
final_list.append([i[1][0],np.min(i[:,1]),np.max(i[:,1])])
print(final_list)
上面的代码将生成如下输出
[[1, 5, 7], [2, 8, 22], [3, 55, 77]]
用numpy做这件事的一种方式, 可以使用numpy.split根据第一个轴中的值将它们拆分为单独的数组。然后你可以找到最小值和最大值 有关拆分及其工作原理的详细信息, 你可以看看答案。我在这里不再重复同样的内容
ar = np.split(a, np.flatnonzero(a[1:,0] != a[:-1,0])+1,axis=0)
上面的行拆分并为轴0中的每个唯一值生成数组列表
上述行将产生如下输出:
[
array([[1, 5],
[1, 7]]),
array([[ 2, 8],
[ 2, 10],
[ 2, 22]]),
array([[ 3, 55],
[ 3, 77]])
]
然后您可以迭代它们,以找到输出中所期望的列表的性质
final_list = []
for i in ar:
final_list.append([i[1][0],np.min(i[:,1]),np.max(i[:,1])])
print(final_list)
上面的代码将生成如下输出
[[1, 5, 7], [2, 8, 22], [3, 55, 77]]
这样做的一种方法(不是很好)是使用普通列表
# convert to list and sort if not already sorted
alist = a.tolist()
alist.sort()
# initial values for looping
currval = alist[0][0]
min = alist[0][1]
max = alist[0][1]
# new list to store results in
result = []
# loop through all rows of alist
for row in alist:
if currval == row[0]: # still same index
max = row[1] # update max
else:
result.append([currval, min, max]) # save row
currval = row[0] # update to next index
min = row[1]
max = row[1]
# save last row
result.append([currval, min, max]) # save row
currval = row[0] # update to next index
min = row[1]
max = row[1]
# convert output to nparray
b = np.array(result)
它利用Python对列表进行排序的行为,通过将具有相同索引的列表分组并按递增顺序排列值,对列表进行良好排序。一种方法是使用普通列表
# convert to list and sort if not already sorted
alist = a.tolist()
alist.sort()
# initial values for looping
currval = alist[0][0]
min = alist[0][1]
max = alist[0][1]
# new list to store results in
result = []
# loop through all rows of alist
for row in alist:
if currval == row[0]: # still same index
max = row[1] # update max
else:
result.append([currval, min, max]) # save row
currval = row[0] # update to next index
min = row[1]
max = row[1]
# save last row
result.append([currval, min, max]) # save row
currval = row[0] # update to next index
min = row[1]
max = row[1]
# convert output to nparray
b = np.array(result)
它利用Python对列表进行排序的行为,通过将具有相同索引的列表分组并按递增顺序排列值,对列表进行良好排序。方法#1
矢量化的NumPy方式是-
def agg_minmax(a):
sidx = np.lexsort(a[:,::-1].T)
b = a[sidx]
m = np.r_[True,b[:-1,0]!=b[1:,0],True]
return np.c_[b[m[:-1],:2], b[m[1:],1]]
样本运行-
# Generic case with input not-necessarily sorted by first col
In [35]: a
Out[35]:
array([[ 3, 77],
[ 2, 8],
[ 1, 7],
[ 2, 10],
[ 1, 5],
[ 3, 55],
[ 2, 22]])
In [36]: agg_minmax(a)
Out[36]:
array([[ 1, 5, 7],
[ 2, 8, 22],
[ 3, 55, 77]])
方法#2
我们可以通过sidx
改进内存,只对第一行进行排序,如下所示-
def agg_minmax_v2(a):
sidx = np.lexsort(a[:,::-1].T)
b = a[sidx,0]
m = np.r_[True,b[:-1]!=b[1:],True]
return np.c_[a[sidx[m[:-1]]],a[sidx[m[1:]],1]]
sidx = (a[:,0]*(a[:,1].max()+1) + a[:,1]).argsort()
# https://stackoverflow.com/a/44999009/ @Divakar
def view1D(a): # a is array
a = np.ascontiguousarray(a)
void_dt = np.dtype((np.void, a.dtype.itemsize * a.shape[1]))
return a.view(void_dt).ravel()
A = view1D(a)
sidx = A.argsort()
如果每组都有很多条目,效果会更好
备选方案#1:使用线性索引映射获取sidx
对于正整数,我们可以假设它们位于2D
网格上,从而得到每行的线性索引等价物。因此,我们将跳过lexsort
,然后像这样得到sidx
-
def agg_minmax_v2(a):
sidx = np.lexsort(a[:,::-1].T)
b = a[sidx,0]
m = np.r_[True,b[:-1]!=b[1:],True]
return np.c_[a[sidx[m[:-1]]],a[sidx[m[1:]],1]]
sidx = (a[:,0]*(a[:,1].max()+1) + a[:,1]).argsort()
# https://stackoverflow.com/a/44999009/ @Divakar
def view1D(a): # a is array
a = np.ascontiguousarray(a)
void_dt = np.dtype((np.void, a.dtype.itemsize * a.shape[1]))
return a.view(void_dt).ravel()
A = view1D(a)
sidx = A.argsort()
获取sidx
后的其余代码在之前发布的两种方法中保持不变
备选方案2:使用视图获取sidx
我们可以使用视图
获取sidx
,然后再次跳过lexsort
,如下所示-
def agg_minmax_v2(a):
sidx = np.lexsort(a[:,::-1].T)
b = a[sidx,0]
m = np.r_[True,b[:-1]!=b[1:],True]
return np.c_[a[sidx[m[:-1]]],a[sidx[m[1:]],1]]
sidx = (a[:,0]*(a[:,1].max()+1) + a[:,1]).argsort()
# https://stackoverflow.com/a/44999009/ @Divakar
def view1D(a): # a is array
a = np.ascontiguousarray(a)
void_dt = np.dtype((np.void, a.dtype.itemsize * a.shape[1]))
return a.view(void_dt).ravel()
A = view1D(a)
sidx = A.argsort()
方法#1
矢量化的NumPy方式是-
def agg_minmax(a):
sidx = np.lexsort(a[:,::-1].T)
b = a[sidx]
m = np.r_[True,b[:-1,0]!=b[1:,0],True]
return np.c_[b[m[:-1],:2], b[m[1:],1]]
样本运行-
# Generic case with input not-necessarily sorted by first col
In [35]: a
Out[35]:
array([[ 3, 77],
[ 2, 8],
[ 1, 7],
[ 2, 10],
[ 1, 5],
[ 3, 55],
[ 2, 22]])
In [36]: agg_minmax(a)
Out[36]:
array([[ 1, 5, 7],
[ 2, 8, 22],
[ 3, 55, 77]])
方法#2
我们可以通过sidx
改进内存,只对第一行进行排序,如下所示-
def agg_minmax_v2(a):
sidx = np.lexsort(a[:,::-1].T)
b = a[sidx,0]
m = np.r_[True,b[:-1]!=b[1:],True]
return np.c_[a[sidx[m[:-1]]],a[sidx[m[1:]],1]]
sidx = (a[:,0]*(a[:,1].max()+1) + a[:,1]).argsort()
# https://stackoverflow.com/a/44999009/ @Divakar
def view1D(a): # a is array
a = np.ascontiguousarray(a)
void_dt = np.dtype((np.void, a.dtype.itemsize * a.shape[1]))
return a.view(void_dt).ravel()
A = view1D(a)
sidx = A.argsort()
如果每组都有很多条目,效果会更好
备选方案#1:使用线性索引映射获取sidx
对于正整数,我们可以假设它们位于2D
网格上,从而得到每行的线性索引等价物。因此,我们将跳过lexsort
,然后像这样得到sidx
-
def agg_minmax_v2(a):
sidx = np.lexsort(a[:,::-1].T)
b = a[sidx,0]
m = np.r_[True,b[:-1]!=b[1:],True]
return np.c_[a[sidx[m[:-1]]],a[sidx[m[1:]],1]]
sidx = (a[:,0]*(a[:,1].max()+1) + a[:,1]).argsort()
# https://stackoverflow.com/a/44999009/ @Divakar
def view1D(a): # a is array
a = np.ascontiguousarray(a)
void_dt = np.dtype((np.void, a.dtype.itemsize * a.shape[1]))
return a.view(void_dt).ravel()
A = view1D(a)
sidx = A.argsort()
获取sidx
后的其余代码在之前发布的两种方法中保持不变
备选方案2:使用视图获取sidx
我们可以使用视图
获取sidx
,然后再次跳过lexsort
,如下所示-
def agg_minmax_v2(a):
sidx = np.lexsort(a[:,::-1].T)
b = a[sidx,0]
m = np.r_[True,b[:-1]!=b[1:],True]
return np.c_[a[sidx[m[:-1]]],a[sidx[m[1:]],1]]
sidx = (a[:,0]*(a[:,1].max()+1) + a[:,1]).argsort()
# https://stackoverflow.com/a/44999009/ @Divakar
def view1D(a): # a is array
a = np.ascontiguousarray(a)
void_dt = np.dtype((np.void, a.dtype.itemsize * a.shape[1]))
return a.view(void_dt).ravel()
A = view1D(a)
sidx = A.argsort()
为了弄清楚你的意图,你能显示你的列表代码吗?@hpaulj我真的很抱歉,我打错了第二个数组,它现在已经修复了。我基本上是在尝试复制numpy中的一个字典,其中键是a[0],值是a[1:],只是为了弄清楚您的意图,您可以显示您的列表代码吗?@hpaulj非常抱歉,我键入了第二个数组,它现在已修复。我基本上是在尝试在numpy中复制一个字典,其中键是a[0],值是a[1:]谢谢您的快速响应,我正在尝试将我的项目包含在numpy中。有可能在numpy中复制相同的东西吗?如果没有,我会继续使用熊猫。@MohammadIslam我可以知道原因吗,为什么numpy的答案不是公认的答案,基于熊猫的答案在哪里?我只是想确定一下,如果我能纠正的话something@venkatakrishnan我很抱歉仓促接受了答案,我将仔细检查每个答案,看看它们的效果如何。我现在没时间,好吧。如果是这样的话,你可以接受任何答案。只是想确定有没有错误。学习愉快。感谢您的快速回复,我正在努力将我的项目包含在numpy中。有可能在numpy中复制相同的东西吗?如果没有,我会继续使用熊猫。@MohammadIslam我可以知道原因吗,为什么numpy的答案不是公认的答案,作为一名pa在哪里