【问题标题】:Pandas: Subtract row mean from each element in rowPandas:从行中的每个元素中减去行平均值
【发布时间】:2014-11-22 17:57:18
【问题描述】:

我有一个数据框,其中的行按化学元素类型索引,列代表不同的样本。这些值是浮点数,表示每个样本中行元素的存在程度。

我想计算每一行的平均值,然后从该特定行中的每个值中减去它以标准化数据,并为该数据集创建一个新的数据框。

我尝试使用 mean(1),它为我提供了一个 Series 对象,其中包含每个化学元素的平均值,这很好,但后来我尝试使用减法,但没有用。

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    您可以使用 DataFrame 的 sub 方法并指定减法应该按行 (axis=0) 发生,而不是默认的按列行为:

    df.sub(df.mean(axis=1), axis=0)
    

    这是一个例子:

    >>> df = pd.DataFrame({'a': [1.5, 2.5], 'b': [0.25, 2.75], 'c': [1.25, 0.75]})
    >>> df
         a     b     c
    0  1.5  0.25  1.25
    1  2.5  2.75  0.75
    

    每一行的平均值很容易计算:

    >>> df.mean(axis=1)
    0    1
    1    2
    dtype: float64
    

    要对 DataFrame 的行进行去均值,只需从 df 中减去行的平均值,如下所示:

    >>> df.sub(df.mean(axis=1), axis=0)
         a     b     c
    0  0.5 -0.75  0.25
    1  0.5  0.75 -1.25
    

    【讨论】:

    • 我认为轴真的很混乱。例如,axis=1 表示逐行平均,但是,axis=1 表示逐列减去,我是否误解了传统如何使用轴?
    • @B.Mr.W.我同意这可能会令人困惑(在处理 NumPy/Pandas 时,我经常被卡住并且不得不使用轴号)。基本上,axis=1 只是意味着“跨越数据帧”。这可能意味着一行中的条目(如df.mean(axis=1)),或者,由于列的名称也跨越DataFrame,当需要引用列名时使用axis=1。我认为 Stack Overflow 上有几个关于这个主题的问题,我回答了其中一个问题here
    【解决方案2】:

    除了@ajcr 的出色回答之外,您可能还需要考虑重新安排存储数据的方式。

    您目前的操作方式(不同列中的不同样本)是您使用电子表格时的表示方式,但这可能不是表示数据的最有用方式。

    通常,每一列代表关于单个现实世界实体的唯一信息。这类数据的典型例子是人:

    id  name  hair_colour  Age
    1   Bob   Brown        25
    

    真的,您的不同样本是不同的现实世界实体

    因此,我建议使用两级索引来描述每条信息。这使得以您想要的方式操作数据更加方便。

    因此:

    >>> df = pd.DataFrame([['Sn',1,2,3],['Pb',2,4,6]],
                          columns=['element', 'A', 'B', 'C']).set_index('element')
    >>> df.columns.name = 'sample'
    >>> df # This is how your DataFrame looks at the moment
    sample   A  B  C
    element         
    Sn       1  2  3
    Pb       2  4  6
    >>> # Now make those columns into a second level of index
    >>> df = df.stack()
    >>> df
    element  sample
    Sn       A         1
             B         2
             C         3
    Pb       A         2
             B         4
             C         6
    

    我们现在可以使用groupby 的所有美味功能:

    >>> demean = lambda x: x - x.mean()
    >>> df.groupby(level='element').transform(demean)
    element  sample
    Sn       A        -1
             B         0
             C         1
    Pb       A        -2
             B         0
             C         2
    

    当您以这种方式查看数据时,您会发现很多很多以前是多列的用例 DataFrames 实际上是 MultiIndexed Series,并且您对数据的处理方式拥有更多的权力被表示和转换。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-09-09
      • 1970-01-01
      • 2018-03-07
      • 2019-03-05
      • 1970-01-01
      • 2015-06-26
      • 1970-01-01
      相关资源
      最近更新 更多