Python Pandas条件转换

时间:2016-11-17 11:16:06

标签: python pandas dataframe transform

我的数据看起来像这样

Plate LogRatio
 1      0.4
 1      0.3
 1      0.2
 2      0.5 
 2      0.3

我想做3种类型的LogRatio 按平板:我不想计算极值LogRatio(分数排除)。

m1 = mean(LogRatio[LogRatio > q20LogRatio & LogRatio < q80LogRatio])
m2 = mean(LogRatio[LogRatio > q25LogRatio & LogRatio < q75LogRatio])
m3 = mean(LogRatio[LogRatio > q30LogRatio & LogRatio < q70LogRatio])
M = (m1 + m2 + m3) / 3 

我试过这样的事情:

df['m1'] = df.groupby('Plate')['LogRatio'].transform(lambda x: ((x > x.quantile(q=0.20)) & (x < x.quantile(q=0.80))).mean())
df['m2'] = df.groupby('Plate')['LogRatio'].transform(lambda x: ((x > x.quantile(q=0.25)) & (x < x.quantile(q=0.75))).mean())
df['m3'] = df.groupby('Plate')['LogRatio'].transform(lambda x: ((x > x.quantile(q=0.30)) & (x < x.quantile(q=0.70))).mean())
df['M'] = (df['m1'] + df['m2'] + df['m3']) / 3

但如果我在Calc上手工完成,那么每个均值的结果都不一样。 这是我在转换函数中的逻辑条件,不能像那样理解吗?我知道结果是错误的,但我的终端没有“错误”,所以我不知道该怎么做。

1 个答案:

答案 0 :(得分:2)

AFAIU我会改变lambda函数,如下所示:

df.groupby('Plate')['LogRatio'].transform(lambda s: s.loc[[True if v < s.quantile(q=0.8) and v > s.quantile(q=0.2) else False for v in s]].mean())

s.loc[]接受与布尔值的可互换,以便对LogRatio进行子集化 - Series

为了使其更具可读性,我将采用以下解决方案:

def quartile_subset(logratios,lower,upper):
    # some comment to describe what you are doing
    return logratios.loc[[True if v < logratios.quantile(q=upper) and v > logratios.quantile(q=lower) else False for v in logratios]]

df.groupby('Plate')['LogRatio'].transform(lambda s: quartile_subset(s,0.2,0.8).mean())