熊猫groupby和按条件检查行过滤

时间:2020-06-26 09:28:20

标签: python pandas dataframe pandas-groupby

我有一个熊猫数据框df

id year variable value
1   19   high     20
1   19   low      10
1   20   high     20
1   20   low      30

我想按ID和年份分组(每个这样的组将只有2行,一个代表高行,另一个代表低行),并检查high变量的值是否实际上大于low变量的值。如果没有,那么我想删除这些组并将它们放在新的数据框中。因此,对于上述内容,我想拥有df

id year variable value
1   19   high     20
1   19   low      10

df2

id year variable value
1   20   high     20
1   20   low      30

4 个答案:

答案 0 :(得分:1)

以下代码无需groupby即可解决该问题。相反,它会旋转变量,然后比较高和低,只保留那些高>低的列,然后再次取消对它们的显示

df.pivot_table(index=['id','year'],columns='variable', values='value').reset_index().query('high>low').melt(id_vars=['id','year'],value_vars=['high','low'])

id  year    variable    value
0   1   19  high    20
1   1   19  low     10

第二个数据框将high>low替换为low>=high

答案 1 :(得分:1)

我们可以使用requireimport来测试更低的> =更高。

groupby

答案 2 :(得分:0)

重新创建您的DataFrame

df = pd.DataFrame(
    {
        "id": 1,
        "year": [19, 19, 20, 20],
        "variable": ["high", "low", "high", "low"],
        "value": [20, 10, 20, 30],
    }
)

遍历groupby组并过滤:

df_res = []
df_res2 = []
for _, df_group in df.groupby(["id", "year"]):

    val_low = df_group.query("variable == 'low'").value.values[0]
    val_high = df_group.query("variable == 'high'").value.values[0]

    if val_high > val_low:
        df_res.append(df_group)
    else:
        df_res2.append(df_group)

df_res = pd.concat(df_res)
df_res2 = pd.concat(df_res2)

print(df_res)
id year variable value
1   19   high     20
1   19   low      10

print(df_res2)
id year variable value
1   20   high     20
1   20   low      30

答案 3 :(得分:0)

初学者:

创建2个包含高和低“变量”值的df:

dfh = df[df["var"]=="high"]
dfh.reset_index(drop=True, inplace=True)

dfl = df[df["var"]=="low"]
dfl.reset_index( drop=True, inplace=True)

进行检查,然后将结果放在新列中:

dfh['greatest'] = np.where(dfh['val'] > dfl['val'], 'True', 'False')
dfl['greatest'] = np.where(dfl['val'] < dfh['val'], 'True', 'False')

合并这两个df:

dfall = pd.concat([dfh,dfl])

最后通过选择有趣的值来创建dfs:

df_great = dfall[dfall["greatest"]=="True"]
df_less = dfall[dfall["greatest"]=="False"]