代码之家  ›  专栏  ›  技术社区  ›  stone rock

如何计算数据帧中特定列的平均值?

  •  -1
  • stone rock  · 技术社区  · 6 年前

    我有一个数据帧,其值类型为: object . 数据帧还包含 NaN 价值观。我想忽略 值和列中所有剩余值的平均值。

    平均值计算如下: 上限值=30 下限值=0

    (上界和下界是固定的,所有值都需要计算出来。)

    所以,

    • 对于'gt;20',平均值=(20+30)/2=25

    • 对于“>1”,平均值=(30+1)/2=15.5

    • 对于“<5”,平均值=(5+0)/2=2.5

    • 对于“<10”,平均值=(10+0)/2=5

    数据帧:

    column1
    >20
    NaN
    <5
    12
    >1
    <10
    NaN
    8
    

    注: 列中的以上值是字符串,我想将其转换为数值。

    最终转换的数据帧应为:

    column1
    25
    NaN
    2.5
    12
    15.5
    5
    NaN
    8
    

    注意:上面的值(如8和12)不会被转换。我只想将前缀为>或<其余值的值从字符串值转换为数字。

    4 回复  |  直到 6 年前
        1
  •  1
  •   gaganso    6 年前

    下面的代码应用一个自定义函数,该函数检查每个元素的第一个字符,并根据该字符计算平均值。

    import numpy as np
    import pandas as pd
    upper = 30
    lower = 0
    
    df = pd.DataFrame({'col1':['>20',np.NaN,'<5','12','>1','<10',np.NaN,'8']})
    def avg(val):
        if val is not np.NaN:
            char = val[0]
            if char == '>':
                res = (float(val[1:])+upper)/2
            elif char == '<':
                res = (float(val[1:])+lower)/2
            else:
                res = float(val)
            return res
    
    print(df["col1"].apply(avg))
    

    输出:

    0    25.0
    1     NaN
    2     2.5
    3    12.0
    4    15.5
    5     5.0
    6     NaN
    7     8.0
    
        2
  •  3
  •   Ashish Acharya    6 年前

    也许还有更好的方法,但这也很有效:

    df['num'] = df.column1.str.extract('(\d+)')
    df['sign'] = df.column1.str.extract('([<>])').fillna('=')
    
    def get_avg(row):
        if not row.num:
            return row.num
        elif row.sign == '>':
            return (int(row.num)+30)/2
        elif row.sign == '>':
            return (int(row.num)+0)/2
        else:
            return row.num
    
    df['avg'] = df.apply(lambda row: get_avg(row), axis=1)
    

    输出:

      column1 sign  num   avg
    0     >20    >   20    25
    1     NaN    =  NaN   NaN
    2      <5    <    5     5
    3      12    =   12    12
    4      >1    >    1  15.5
    5     <10    <   10    10
    6     NaN    =  NaN   NaN
    7       8    =    8     8
    
        3
  •  1
  •   ALollz    6 年前

    你可以用 np.select 指定要平均的值。然后,在将第1列转换为数字后,可以求平均值。

    import pandas as pd
    import numpy as np
    
    lt = df[df.column1.notnull()].column1.str.contains('<')
    gt = df[df.column1.notnull()].column1.str.contains('>')
    
    conds = [lt, gt, ~(lt | gt)]
    choice = [0, 30, pd.to_numeric(df[df.column1.notnull()].column1, errors='coerce')]
    
    df.loc[df.column1.notnull(), 'column2'] = np.select(conds, choice)
    df['column1'] = pd.to_numeric(df.column1.str.replace('<|>', ''))
    
    df['Avg'] = df.mean(axis=1)
    

    输出:

       column1  column2   Avg
    0     20.0     30.0  25.0
    1      NaN      NaN   NaN
    2      5.0      0.0   2.5
    3     12.0     12.0  12.0
    4      1.0     30.0  15.5
    5     10.0      0.0   5.0
    6      NaN      NaN   NaN
    7      8.0      8.0   8.0
    
        4
  •  1
  •   iMad    6 年前

    您可以编写一个函数来计算您的“自定义平均值”,然后在您的列上调用Apply。

    x = np.array([['>20'],[np.NaN],['<5'],['>1'],['<10'],[np.NaN]])
    df = pd.DataFrame(x,columns=["column1"])
    def myFunc(content, up, low):
        try:
            if content.isnumeric(): return float(content)
            return {
                '>': (float(content[1:])+up)/2,
                '<': (float(content[1:])+low)/2
            }[content[0]]
        except:
            return np.nan
    
    df["avg"] = df.column1.apply(lambda x: myFunc(x, up=30, low=0))