创建复杂的条件列(几何平均值)Python

时间:2016-04-02 18:57:36

标签: python pandas

我正在尝试在df中创建一个列,告诉我给定时间的水是否具有可游泳的质量。我用几何平均值撞墙。

这是一个迷你样本,就像我正在使用的那样:

<div data-sly-foo="${properties.jcr:description}">This text should get replaced</div>

这些是使游泳水不能接受的条件:
EnteroCount&gt; = 110
OR
五个或更多样本的几何平均值(加权平均值)大于30

我想创建一个只根据这两个条件赋予“可接受”或“不可接受”值的列。我可以在第一个条件下执行以下操作,但引入gmean并不是那么容易(或者是它):

df = pd.DataFrame({'Site': ['A', 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'C'], 'EnteroCount': [1733, 4, 20, 150, 70, 1500, 55, 22, 180]})
df["Site"] = df["Site"].astype('category')

很想知道如何有效地完成这项工作。

1 个答案:

答案 0 :(得分:4)

计算每个站点的几何平均值并检查它是否大于30:

>>> df['geo_mean_acceptable'] = (
        df.groupby('Site')
          .transform(lambda group: group.prod() ** (1 / float(len(group))) > 30)
          .astype(bool))

这得到了每个站点的几何平均值:

>>> df.groupby('Site').EnteroCount.apply(lambda group: group.product() ** (1 / float(len(group))))
Site
A     68.016702
B    121.981006
C    180.000000
Name: EnteroCount, dtype: float64

使用scipy的几何平均函数:

from scipy.stats.mstats import gmean

>>> df.groupby('Site').EnteroCount.apply(gmean)
Site
A     68.016702
B    121.981006
C    180.000000
Name: EnteroCount, dtype: float64

鉴于五个最高值将为您提供组中最高的几何平均值,您可以使用:

df.groupby('Site').EnteroCount.apply(lambda group: gmean(group.nlargest(5)))

您可以看到它是如何按组选择最大的五个值,然后将其用作gmean的参数:

>>> df.groupby('Site').EnteroCount.apply(lambda group: group.nlargest(5).values.tolist())
Site
A    [1733, 150, 70, 20, 4]
B            [1500, 55, 22]
C                     [180]
Name: EnteroCount, dtype: object

<强>摘要

df['swim'] = np.where(
    (df.groupby('Site').EnteroCount.transform(max) > 110) |
    (df.groupby('Site').EnteroCount.transform(lambda group: gmean(group.nlargest(5))) > 30), 
    'unacceptable', 'acceptable')