Python 对行执行groupby和filter by条件检查

Python 对行执行groupby和filter by条件检查,python,pandas,dataframe,pandas-groupby,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 year variable value 1 19 high 20 1 19 low 10 我想按id和年份分组(每个这样的组只有两行,一行表示高,另一行表示低),并检查高变量的值是否实际大于低变量的值。如果没有,我

我有一个熊猫数据帧,
df

id year variable value
1   19   high     20
1   19   low      10
1   20   high     20
1   20   low      30
id year variable value
1   19   high     20
1   19   low      10
我想按id和年份分组(每个这样的组只有两行,一行表示高,另一行表示低),并检查高变量的值是否实际大于低变量的值。如果没有,我想删除这些组并将它们放在一个新的数据帧中。因此,对于以上内容,我希望有,
df

id year variable value
1   19   high     20
1   19   low      10
1   20   high     20
1   20   low      30
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

重新创建数据帧

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

重新创建数据帧

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

下面的代码将在不需要groupby的情况下解决此问题。它代替了旋转变量,然后比较高和低,只保留那些高>低的列,然后再次取消对它们的PIVOT

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

第二个数据帧将用
low>=high

替换
high>low
,下面的代码将在不需要分组的情况下解决它。它代替了旋转变量,然后比较高和低,只保留那些高>低的列,然后再次取消对它们的PIVOT

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

第二个数据帧将用初学者提供的
low>=high
替换
high>low

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
创建2个df,其中包含高和低“变量”值:

进行检查并将结果放入新列中:

dfh['greatest'] = np.where(dfh['val'] > dfl['val'], 'True', 'False')
dfl['greatest'] = np.where(dfl['val'] < dfh['val'], 'True', 'False')
最后,通过选择感兴趣的值来创建dfs:

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

来自初学者:

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
创建2个df,其中包含高和低“变量”值:

进行检查并将结果放入新列中:

dfh['greatest'] = np.where(dfh['val'] > dfl['val'], 'True', 'False')
dfl['greatest'] = np.where(dfl['val'] < dfh['val'], 'True', 'False')
最后,通过选择感兴趣的值来创建dfs:

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

我们可以使用
groupby
diff
来测试下限>=上限

s = df.groupby(['id','year','variable']).first().unstack(-1).sort_index(axis=1)
#sort index is to order the columns. 
df_new = s[s.diff(axis=1).ge(0).any(1)].stack(1).reset_index()

print(df_new)

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

我们可以使用
groupby
diff
来测试下限>=上限

s = df.groupby(['id','year','variable']).first().unstack(-1).sort_index(axis=1)
#sort index is to order the columns. 
df_new = s[s.diff(axis=1).ge(0).any(1)].stack(1).reset_index()

print(df_new)

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

嗨,新手。unstack(-1)到底在做什么?它似乎正在将列转换为多索引列?嗨,数据新手。unstack(-1)到底在做什么?它似乎正在将列转换为多索引列?