给定可变数量的条件,如何在数据帧上设置值?
How set value on dataframe given a variable number of conditions?
from itertools import product
import pandas as pd
animals = ["dogs", "cats"]
eyes = ['brown', 'blue', 'green']
height = ['short', 'average', 'tall']
a = [animals, eyes, height]
df = pd.DataFrame(list(product(*a)), columns=["animals", "eyes", "height"])
df['value'] = 1
输出:
animals eyes height value
0 dogs brown short 1
1 dogs brown average 1
2 dogs brown tall 1
3 dogs blue short 1
4 dogs blue average 1
5 dogs blue tall 1
6 dogs green short 1
问题:
如何创建单个函数,以便在给定一个或多个条件的情况下在一行或多行中为零 "value"?
示例:
# This would change all the 1s into 0s for all dogs with blue eyes.
zero_out(df, [("animals", "dogs"), ("eyes", "blue")])
# This would change all the 1s into 0s for all tall animals.
zero_out(df, [("height", "tall")])
到目前为止我的尝试:
我尝试使用 *unpacking 来做到这一点,但没有成功,因为我不知道如何使用解包变量设置多个条件。如果我硬编码条件的数量,那么设置多个条件很容易......
df[(condition1) & (condition2) & (condition3)] = 0
此外,也许这超出了问题的范围,我如何使用*解包(或不对 if 语句中的条件数进行硬编码)在给定常规 if 语句的情况下设置可变数量的条件?
例如
if a > 0 and b > 4
#Or...
if a > 0 and b > 4 and c < 2
感谢您的帮助。
如果我没理解错的话,你正在寻找.query()
方法:
import pandas as pd
from itertools import product
animals = ["dogs", "cats"]
eyes = ['brown', 'blue', 'green']
height = ['short', 'average', 'tall']
a = [animals, eyes, height]
df = pd.DataFrame(list(product(*a)), columns=["animals", "eyes", "height"])
df['value'] = 1
def zero_out(df, lst):
q = ' & '.join( '{} == "{}"'.format(col, val) for col, val in lst )
df.loc[df.query(q).index, 'value'] = 0
zero_out(df, [("height", "tall")])
print(df)
打印:
animals eyes height value
0 dogs brown short 1
1 dogs brown average 1
2 dogs brown tall 0
3 dogs blue short 1
4 dogs blue average 1
5 dogs blue tall 0
6 dogs green short 1
7 dogs green average 1
8 dogs green tall 0
9 cats brown short 1
10 cats brown average 1
11 cats brown tall 0
12 cats blue short 1
13 cats blue average 1
14 cats blue tall 0
15 cats green short 1
16 cats green average 1
17 cats green tall 0
或zero_out(df, [("animals", "dogs"), ("eyes", "blue")])
:
animals eyes height value
0 dogs brown short 1
1 dogs brown average 1
2 dogs brown tall 1
3 dogs blue short 0
4 dogs blue average 0
5 dogs blue tall 0
6 dogs green short 1
7 dogs green average 1
8 dogs green tall 1
9 cats brown short 1
10 cats brown average 1
11 cats brown tall 1
12 cats blue short 1
13 cats blue average 1
14 cats blue tall 1
15 cats green short 1
16 cats green average 1
17 cats green tall 1
def zero_out(df, list_of_filters, out_column='value'):
conds = np.ones(df.shape[0], dtype=bool)
for col_name, val in list_of_filters:
cond = df[col_name].eq(val)
conds &= cond
df.loc[conds, out_column] = 0
return df
您也可以使用它。它比 Andrej 的方法稍微更通用一些,因为它不假定过滤器值是字符串。
你可以试试:
def zero_out(df, *args):
df_temp = df.copy()
for arg in args:
df_temp = df_temp[df_temp[arg[0]] == arg[1]].copy()
df.iloc[df_temp.index, -1] = 0
return df
zero_out(df, ("animals", "dogs"), ("eyes", "blue"))
结果:
animals eyes height value
0 dogs brown short 0
1 dogs brown average 0
2 dogs brown tall 0
3 dogs blue short 0
4 dogs blue average 0
5 dogs blue tall 0
6 dogs green short 0
7 dogs green average 0
8 dogs green tall 0
9 cats brown short 1
10 cats brown average 1
11 cats brown tall 1
12 cats blue short 0
13 cats blue average 0
14 cats blue tall 0
15 cats green short 1
16 cats green average 1
17 cats green tall 1
from itertools import product
import pandas as pd
animals = ["dogs", "cats"]
eyes = ['brown', 'blue', 'green']
height = ['short', 'average', 'tall']
a = [animals, eyes, height]
df = pd.DataFrame(list(product(*a)), columns=["animals", "eyes", "height"])
df['value'] = 1
输出:
animals eyes height value
0 dogs brown short 1
1 dogs brown average 1
2 dogs brown tall 1
3 dogs blue short 1
4 dogs blue average 1
5 dogs blue tall 1
6 dogs green short 1
问题: 如何创建单个函数,以便在给定一个或多个条件的情况下在一行或多行中为零 "value"?
示例:
# This would change all the 1s into 0s for all dogs with blue eyes.
zero_out(df, [("animals", "dogs"), ("eyes", "blue")])
# This would change all the 1s into 0s for all tall animals.
zero_out(df, [("height", "tall")])
到目前为止我的尝试:
我尝试使用 *unpacking 来做到这一点,但没有成功,因为我不知道如何使用解包变量设置多个条件。如果我硬编码条件的数量,那么设置多个条件很容易......
df[(condition1) & (condition2) & (condition3)] = 0
此外,也许这超出了问题的范围,我如何使用*解包(或不对 if 语句中的条件数进行硬编码)在给定常规 if 语句的情况下设置可变数量的条件?
例如
if a > 0 and b > 4
#Or...
if a > 0 and b > 4 and c < 2
感谢您的帮助。
如果我没理解错的话,你正在寻找.query()
方法:
import pandas as pd
from itertools import product
animals = ["dogs", "cats"]
eyes = ['brown', 'blue', 'green']
height = ['short', 'average', 'tall']
a = [animals, eyes, height]
df = pd.DataFrame(list(product(*a)), columns=["animals", "eyes", "height"])
df['value'] = 1
def zero_out(df, lst):
q = ' & '.join( '{} == "{}"'.format(col, val) for col, val in lst )
df.loc[df.query(q).index, 'value'] = 0
zero_out(df, [("height", "tall")])
print(df)
打印:
animals eyes height value
0 dogs brown short 1
1 dogs brown average 1
2 dogs brown tall 0
3 dogs blue short 1
4 dogs blue average 1
5 dogs blue tall 0
6 dogs green short 1
7 dogs green average 1
8 dogs green tall 0
9 cats brown short 1
10 cats brown average 1
11 cats brown tall 0
12 cats blue short 1
13 cats blue average 1
14 cats blue tall 0
15 cats green short 1
16 cats green average 1
17 cats green tall 0
或zero_out(df, [("animals", "dogs"), ("eyes", "blue")])
:
animals eyes height value
0 dogs brown short 1
1 dogs brown average 1
2 dogs brown tall 1
3 dogs blue short 0
4 dogs blue average 0
5 dogs blue tall 0
6 dogs green short 1
7 dogs green average 1
8 dogs green tall 1
9 cats brown short 1
10 cats brown average 1
11 cats brown tall 1
12 cats blue short 1
13 cats blue average 1
14 cats blue tall 1
15 cats green short 1
16 cats green average 1
17 cats green tall 1
def zero_out(df, list_of_filters, out_column='value'):
conds = np.ones(df.shape[0], dtype=bool)
for col_name, val in list_of_filters:
cond = df[col_name].eq(val)
conds &= cond
df.loc[conds, out_column] = 0
return df
您也可以使用它。它比 Andrej 的方法稍微更通用一些,因为它不假定过滤器值是字符串。
你可以试试:
def zero_out(df, *args):
df_temp = df.copy()
for arg in args:
df_temp = df_temp[df_temp[arg[0]] == arg[1]].copy()
df.iloc[df_temp.index, -1] = 0
return df
zero_out(df, ("animals", "dogs"), ("eyes", "blue"))
结果:
animals eyes height value
0 dogs brown short 0
1 dogs brown average 0
2 dogs brown tall 0
3 dogs blue short 0
4 dogs blue average 0
5 dogs blue tall 0
6 dogs green short 0
7 dogs green average 0
8 dogs green tall 0
9 cats brown short 1
10 cats brown average 1
11 cats brown tall 1
12 cats blue short 0
13 cats blue average 0
14 cats blue tall 0
15 cats green short 1
16 cats green average 1
17 cats green tall 1