【问题标题】:Calculate mean val from column excluding 'None' values从不包括“无”值的列中计算平均值
【发布时间】:2013-10-23 07:06:13
【问题描述】:

我有大量制表符分隔的数据。我想计算每列的平均值。问题是某些值是“无”,我想执行计算并排除这些数据点。

数据结构如下:

0.0     0.5     0.0     0.142857142857  0.0     0.0
0.0     0.0     0.0     0.0             0.0     0.0
0.0     0.8     0.0     None            0.0     0.0

我正在使用此代码。不知道如何将条件添加到此:

data = [float(l.split('\t')[target_column_val]) \
           for l in open(target_file, 'r').readlines()]
mean = sum(data) / len(data)

【问题讨论】:

    标签: python math multiple-columns mean nonetype


    【解决方案1】:

    open 的默认模式为rread。所以,我没有在open 中添加r。我们从中得到一个文件对象ff 是可迭代的,所以我们循环遍历 f 中的所有行。

    在我们这样做之后,我们可以用空格分割行,所以我们为什么使用for item in var.split(),它为我们提供了一个字符串列表,这些字符串是通过在f中分割行形成的。

    我们使用if != 'None',因为这是在此处摆脱"None" 值的一种方式。最后我们附加float(item)。因为我们想要浮点数而不是字符串。

    with open('targe_file.txt') as f:
        final_list = [float(item) for var in f for item in var.split() if item != 'None']  # None is a string in this instance.
    
    print final_list
    

    试试上面的代码,你可以将 if 语句添加到列表推导中迭代之后。

    然后您可以像这样计算平均值:

    mean = sum(final_list) / len(final_list)
    

    我们可以使用sum 函数将列表中的所有浮点数相加。 sum 函数接收一个可迭代的对象,类似于list(我们的例子)或tuplelen 为您提供列表的长度。

    【讨论】:

    • 我好像回答错了,请等我更新。
    【解决方案2】:

    寻找mapzip 函数。这是一些示例(修改它以满足您的需求)

    >>> from numpy import mean
    >>>
    >>> def safe_float(s):
    ...     try:
    ...         return float(s)
    ...     except ValueError:
    ...         return s
    ...
    >>> def filter_none(lst):
    ...     return filter(lambda x: x<>'None', lst)
    ...
    >>> source = ['0.0 0.5 0.0 0.142857142857 0.0 0.0',
    ...           '0.0 0.0 0.0 0.0 0.0 0.0',
    ...           '0.0 0.8 0.0 None 0.0 0.0']
    >>>
    >>> data = [map(safe_float, l.split()) for l in source]
    >>> filtered_columns = map(filter_none, zip(*data))
    >>> print map(mean, filtered_columns)
    [0.0, 0.43333333333333335, 0.0, 0.071428571428499996, 0.0, 0.0]
    

    【讨论】:

      【解决方案3】:

      您可以在推导中包含 if 子句:

      [l for l in (stuff) if l != 'None']
      

      看看我认为你正在尝试做的事情,我认为应该这样做:

      with open(target_file) as infile:
          col = (line.split('\t')[target_column_val] for line in infile)
          data = [float(x) for x in col if x != 'None']
          mean = sum(data)/len(data)
      

      我的 cmets 中答案的问题在于,我认为它会将列向左移动,并可能导致您获得您可能不想要的值。

      【讨论】:

      • 好的,谢谢。但是我如何为 l.split('\t') 数组中的每个元素合并 if 子句?例如,在每一行中可能有 1 个或多个“无”值,我想跳过这些。
      • 我刚刚意识到可能会使事情复杂化的事情。 target_column_val 是什么?
      • 除此之外,如果您将l.split() 替换为[val for val in l.split() if val is not None] 之类的东西,那么这会将所有None 值从列表中过滤掉。我只是不知道这是否会弄乱您的索引。
      • @ChadMiller None 必须是字符串。
      猜你喜欢
      • 2019-04-03
      • 2021-11-22
      • 2016-10-02
      • 2012-05-31
      • 1970-01-01
      • 1970-01-01
      • 2017-01-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多