【问题标题】:Calculate the row average of selected columns计算选定列的行平均值
【发布时间】:2016-10-13 10:58:00
【问题描述】:

我有一个 csv 文件:

#col1 #col2 ... #col253
33,    123, ...    99
19,    409, ...    24
34,    239, ...    60
...    ...  ...    ..

还有一个字典,其值存储所选列的开始和结束索引:

d = {
    'win': [(11, 55), (194, 233)],
    'lose': [(72, 111), (133, 172)],
    'neut': [(0, 10), (51, 71), (112, 132), (173, 193)]
    }

我的目标是计算字典中某个键的所有选定列的每行平均值。

例如,对于第一行的'win' 块,选择11, 12, ...55, 194, 195,...233 列并计算平均值。

我现在使用的是什么:

x = np.loadtxt('filename.csv', delimiter=',')
for line in x:
    selected = [line[start:end + 1] for (start, end) in d['win']]
    ...

selected 将是[array([39, 12, 94,...]), array([3, 4, ...])],不能传递给np.mean()

所以列表中的数组应该合并为一个,我不知道如何优雅地做,或者迭代地将所有数字相加然后取平均值,我认为这很难看。


已编辑:

一个丑陋的方法可能是:

average = sum(map(sum, selected)) / sum(map(len, selected))

【问题讨论】:

  • 您是在寻找每行的总平均值,还是每行的平均值?从您的示例来看,它看起来像是每行单独的方法。
  • @IljaEverilä 对于每一行,抱歉描述不好。

标签: python csv numpy


【解决方案1】:

您可以使用this other solution 以矢量化方式创建一个包含所有这些interval-ed 范围的列数组。然后,用这些索引输入数组x 的列,并计算沿第二个轴(axis=1) 的平均值。

为了方便读者,让我在这里再次列出向量化函数来创建一个这样的 interval-ed 范围的数组 -

def using_ones_cumsum_v2(array1, array2):
    lens = array2 - array1
    id_arr = np.ones(lens.sum(),dtype=array1.dtype)
    id_arr[lens[:-1].cumsum()] = np.diff(array1) - lens[:-1]+1
    id_arr[0] = array1[0]
    return id_arr.cumsum()

有了它,我们将得到 win 键的平均值,就像这样 -

d_win = np.array(d['win'])
out_win = x[:,using_ones_cumsum_v2(d_win[:,0],d_win[:,1]+1)].mean(1)

示例运行以演示使用 using_ones_cumsum_v2 创建 interval-ed 范围 -

In [24]: d = {
    ...:     'win': [(1, 3), (5, 8)],
    ...:     'lose': [(2, 5), (7, 8)],
    ...:     'neut': [(0, 1), (4, 7), (8, 9)]
    ...:     }

In [25]: d_win = np.array(d['win'])

In [26]: d_win
Out[26]: 
array([[1, 3],
       [5, 8]])

In [27]: using_ones_cumsum_v2(d_win[:,0],d_win[:,1]+1)
Out[27]: array([1, 2, 3, 5, 6, 7, 8])

【讨论】:

    【解决方案2】:

    Numpy 数组支持rich indexing,因此这可以通过例如对所有行进行切片并传递一个列列表以供选择来实现。

    要分别计算每一行,您可以传递axis(或坐标轴),沿其计算均值作为mean() 的参数:

    columns = np.hstack(tuple(np.arange(a, b + 1) for a, b in d['win']))
    row_means = x[:, columns].mean(axis=1)
    

    【讨论】:

    • 是的,这就是我要找的,非常感谢,兄弟!
    猜你喜欢
    • 2022-01-08
    • 2019-04-03
    • 1970-01-01
    • 2016-07-27
    • 1970-01-01
    • 2023-03-27
    • 1970-01-01
    • 2011-05-17
    • 1970-01-01
    相关资源
    最近更新 更多