我有一个数据框,其中行由化学元素类型索引,而列表示不同的样本。值是浮点数,表示每个样本中行元素的存在程度。
我想计算每一行的平均值,并从该特定行中的每个值中减去它以规范化数据,并为该数据集创建一个新的数据帧。
我尝试使用mean(1),它给了我一个具有每个化学元素均值的Series对象,这很好,但后来我尝试使用减法,这不起作用。
答案 0 :(得分:29)
您可以使用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
答案 1 :(得分:6)
除了@ 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
,并且您有很多更多地掌握数据的表示和转换方式。