【问题标题】:Combine a 2d numpy array grouped by values in a column组合按列中的值分组的 2d numpy 数组
【发布时间】:2018-10-13 16:43:58
【问题描述】:

我有这个数组:

[['Burgundy Bichon Frise' '1' '137']
['Pumpkin Pomeranian' '1' '182']
['Purple Puffin' '1' '125']
['Wisteria Wombat' '1' '109']
['Burgundy Bichon Frise' '2' '168']
['Pumpkin Pomeranian' '2' '141']
['Purple Puffin' '2' '143']
['Wisteria Wombat' '2' '167']
['Burgundy Bichon Frise' '3' '154']
['Pumpkin Pomeranian' '3' '175']
['Purple Puffin' '3' '128']
['Wisteria Wombat' '3' '167']]

第一个索引包含动物的名称,第二个是它所在的地区,第三个是人口。我需要获得每个区域中物种的平均值,并获得每个区域中每个物种的最大值和最小值。所以对于“Purple Puffins”,平均值应该是 (125+143+128)/3 = 132

我很困惑如何让 numpy 数组只计算每个区域的人口。

将这个二维数组分成多个二维数组会更好或更容易吗?

【问题讨论】:

  • 这是一个 numpy 字符串数组?
  • 然而,每个区域中每个物种的平均值在这里相当奇怪,因为在这里看起来每个动物区域元组只出现一次。
  • @WillemVanOnsem,是的,但我至少需要第三列是整数。至于每个物种的平均值。我的意思是每个地区的同一物种的平均值。因此,所有地区“紫海雀”的平均值应为 132。对措辞错误表示歉意。

标签: python numpy numpy-ndarray


【解决方案1】:

这看起来更像是pandas的任务,我们可以先构造一个dataframe:

import pandas as pd

df = pd.DataFrame([
    ['Burgundy Bichon Frise','1','137'],
    ['Pumpkin Pomeranian','1','182'],
    ['Purple Puffin','1','125'],
    ['Wisteria Wombat','1','109'],
    ['Burgundy Bichon Frise','2','168'],
    ['Pumpkin Pomeranian','2','141'],
    ['Purple Puffin','2','143'],
    ['Wisteria Wombat','2','167'],
    ['Burgundy Bichon Frise','3','154'],
    ['Pumpkin Pomeranian','3','175'],
    ['Purple Puffin','3','128'],
    ['Wisteria Wombat','3','167']], columns=['animal', 'region', 'n'])

接下来我们可以将regionn 转换为数字,这样可以更轻松地计算统计数据:

df.region = pd.to_numeric(df.region)
df.n = pd.to_numeric(df.n)

最后我们可以执行.groupby(..),然后计算一个聚合,比如:

>>> df[['animal', 'n']].groupby(('animal')).min()
                         n
animal                    
Burgundy Bichon Frise  137
Pumpkin Pomeranian     141
Purple Puffin          125
Wisteria Wombat        109
>>> df[['animal', 'n']].groupby(('animal')).max()
                         n
animal                    
Burgundy Bichon Frise  168
Pumpkin Pomeranian     182
Purple Puffin          143
Wisteria Wombat        167
>>> df[['animal', 'n']].groupby(('animal')).mean()
                                n
animal                           
Burgundy Bichon Frise  153.000000
Pumpkin Pomeranian     166.000000
Purple Puffin          132.000000
Wisteria Wombat        147.666667

编辑:获取个动物的最小行

我们可以使用idxmin/idxmax获取per动物的最小/最大行的索引号,然后使用df.iloc[..]获取这些行,例如:

>>> df.ix[df.groupby(('animal'))['n'].idxmin()]
                  animal  region    n
0  Burgundy Bichon Frise       1  137
5     Pumpkin Pomeranian       2  141
2          Purple Puffin       1  125
3        Wisteria Wombat       1  109
>>> df.ix[df.groupby(('animal'))['n'].idxmax()]
                  animal  region    n
4  Burgundy Bichon Frise       2  168
1     Pumpkin Pomeranian       1  182
6          Purple Puffin       2  143
7        Wisteria Wombat       2  167

这里的0, 5, 2, 3(对于idxmin)是数据帧的“行号”。

【讨论】:

  • 对于最小值、最大值和平均值,我如何知道这些数字位于哪个区域?例如,区域 1 中“Burgundy Bichon Frise”的最小值为 137,但代码并没有告诉我。
  • @FunGryphon:见编辑。至于平均值,当然没有区域(平均值没有“附加”到特定区域)。
  • 所以,假设我想要所有区域中的一个最大值。我该如何挑选呢?如果我想从最大值中获取南瓜博美犬?
  • 你过滤df.ix[df[df.animal == 'Pumpkin Pomeranian']['n'].idxmin()]
【解决方案2】:

这里是如何使用 numpy 将数据a 转换为二维表:

>>> unqr, invr = np.unique(a[:, 0], return_inverse=True)
>>> unqc, invc = np.unique(a[:, 1], return_inverse=True)
# initialize with nans in case there are missing values
# these are then treated correctly by nanmean etc.:
>>> out = np.full((unqr.size, unqc.size), np.nan)
>>> out[invr, invc] = a[:, 2]
>>> 
# now we have a table
>>> out
array([[137., 168., 154.],
       [182., 141., 175.],
       [125., 143., 128.],
       [109., 167., 167.]])
# with rows
>>> unqr
array(['Burgundy Bichon Frise', 'Pumpkin Pomeranian', 'Purple Puffin',
       'Wisteria Wombat'], dtype='<U21')
# and columns
>>> unqc
array(['1', '2', '3'], dtype='<U21')
>>> 
# find the mean for 'Purple Puffin':
>>> np.nanmean(out[unqr.searchsorted('Purple Puffin')])
132.0
# find the max for region '2'
>>> np.nanmax(out[:, unqc.searchsorted('2')])
168.0

【讨论】:

    猜你喜欢
    • 2019-01-18
    • 1970-01-01
    • 2011-06-05
    • 2022-08-16
    • 2013-07-08
    • 2020-03-18
    • 2012-12-23
    • 1970-01-01
    • 2017-11-15
    相关资源
    最近更新 更多