Pandas: Subtract row mean from each element in row

前端 未结 2 1202
面向向阳花
面向向阳花 2020-12-29 07:39

I have a dataframe with rows indexed by chemical element type and columns representing different samples. The values are floats representing the degree of presence of the ro

相关标签:
2条回答
  • 2020-12-29 08:19

    Additionally to @ajcr's excellent answer, you might want to consider rearranging how you store your data.

    The way you're doing it at the moment, with different samples in different columns, is the way it would be represented if you were using a spreadsheet, but this might not be the most helpful way to represent your data.

    Normally, each column represents a unique piece of information about a single real-world entity. The typical example of this kind of data is a person:

    id  name  hair_colour  Age
    1   Bob   Brown        25
    

    Really, your different samples are different real-world entities.

    I would therefore suggest having a two-level index to describe each single piece of information. This makes manipulating your data in the way you want far more convenient.

    Thus:

    >>> 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
    

    We now have all the delicious functionality of groupby at our disposal:

    >>> 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
    

    When you view your data in this way, you'll find that many, many use cases which used to be multi-column DataFrames are in fact MultiIndexed Series, and you have much more power over how the data is represented and transformed.

    0 讨论(0)
  • 2020-12-29 08:21

    You could use DataFrame's sub method and specify that the subtraction should happen row-wise (axis=0) as opposed to the default column-wise behaviour:

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

    Here's an example:

    >>> 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
    

    The mean of each row is straightforward to calculate:

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

    To de-mean the rows of the DataFrame, just subtract the mean values of rows from df like this:

    >>> 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
    
    0 讨论(0)
提交回复
热议问题