【发布时间】:2017-12-14 07:15:21
【问题描述】:
我正在尝试对 pandas 数据表中的实验数据进行规范化,该数据表包含多个具有数字可观察值(特征)的列、具有日期和实验条件的列以及其他非数字条件(例如文件名)。
我愿意
- 使用拆分-应用-组合范例
- 在组内标准化,使用子组的聚合统计数据
- 使用不同的归一化(例如除以控制均值、Z 分数)
- 将此应用于所有数值列(可观察值)
- 最后,生成一个增强数据表,其结构与原始数据表相同,但具有额外的列,例如对于 Observable1 列,应该添加一个列 normalized_Observable1
使用此代码sn -p:: 可以生成具有这种结构的简化数据表:
import numpy as np
import pandas as pd
df = pd.DataFrame({
'condition': ['ctrl', 'abc', 'ctrl', 'abc', 'def', 'ctlr', 'ctlr', 'asdasd', 'afff', 'afff', 'gr1','gr2', 'gr2', 'ctrl', 'ctrl', 'kjkj','asht','ctrl'],
'date': ['20170131', '20170131', '20170131', '20170131','20170131', '20170606', '20170606', '20170606', '20170606', '20170606', '20170404', '20170404', '20170404', '20170404', '20170404', '20161212', '20161212', '20161212'],
'observation1': [1.2, 2.2, 1.3, 1.1, 2.3 , 2.3, 4.2, 3.3, 5.1, 3.3, 3.4, 5.5, 9.9, 3.2, 1.1, 3.3, 1.2, 5.4],
'observation2': [3.1, 2.2, 2.1, 1.2, 2.4, 1.2, 1.5, 1.33, 1.5, 1.6, 1.4, 1.3, 0.9, 0.78, 1.2, 4.0, 5.0, 6.0],
'observation3': [2.0, 1.2, 1.2, 2.01, 2.55, 2.05, 1.66, 3.2, 3.21, 3.04, 8.01, 9.1, 7.06, 8.1, 7.9, 5.12, 5.23, 5.15],
'rawsource': ["1.tif", "2.tif", "3.tif", "4.tif", "5.tif","6.tif", "7.tif", "8.tif", "9.tif", "10.tif", "11.tif", "12.tif", "13.tif", "14.tif", "15.tif", "16.tif", "17.tif", "18.tif"]
})
print(df)
看起来像这样
condition date observation1 observation2 observation3 rawsource
0 ctrl 20170131 1.2 3.10 2.00 1.tif
1 abc 20170131 2.2 2.20 1.20 2.tif
2 ctrl 20170131 1.3 2.10 1.20 3.tif
3 abc 20170131 1.1 1.20 2.01 4.tif
4 def 20170131 2.3 2.40 2.55 5.tif
5 ctlr 20170606 2.3 1.20 2.05 6.tif
6 ctlr 20170606 4.2 1.50 1.66 7.tif
7 asdasd 20170606 3.3 1.33 3.20 8.tif
8 afff 20170606 5.1 1.50 3.21 9.tif
9 afff 20170606 3.3 1.60 3.04 10.tif
10 gr1 20170404 3.4 1.40 8.01 11.tif
11 gr2 20170404 5.5 1.30 9.10 12.tif
12 gr2 20170404 9.9 0.90 7.06 13.tif
13 ctrl 20170404 3.2 0.78 8.10 14.tif
14 ctrl 20170404 1.1 1.20 7.90 15.tif
15 kjkj 20161212 3.3 4.00 5.12 16.tif
16 asht 20161212 1.2 5.00 5.23 17.tif
17 ctrl 20161212 5.4 6.00 5.15 18.tif
现在,对于每个实验日期,我都有不同的实验条件,但我总是有一个名为 ctrl 的条件。我想要执行的标准化之一是计算(对于每个数值列)该日期的对照实验的平均值,然后将该日期的所有可观察值除以它们相应的平均值。
我可以使用以下方法快速计算一些按日期、按条件汇总的统计数据:
grsummary = df.groupby(["date","condition"]).agg((min, max, np.nanmean, np.nanstd))
然后我想将这些汇总统计数据应用于每个实验日期的标准化:
grdate = df.groupby("date")
并以如下方式应用规范化:
def normalize_by_ctrlmean(grp_frame, summarystats):
# the following is only pseudo-code as I don't know how to do this
grp_frame/ summarystats(nanmean)
grdate.apply(normalize_by_cntrlmean, summarystats= grsummary)
最后一步只是伪代码。这就是我正在努力解决的问题。我可以使用嵌套的 for 循环对数字列的日期、条件和列名进行规范化,但我是 split-apply-combine 范式的新手,我认为必须有一个简单的解决方案? 非常感谢任何帮助。
【问题讨论】:
标签: python pandas normalization split-apply-combine