我有一个像这样的数据框
ID 8-Jan 15-Jan 22-Jan 29-Jan 5-Feb 12-Feb LowerBound UpperBound Problem
001 618 720 645 573 503 447 401.329 662.670 False
002 62 80 67 94 81 65 45.710 126.289 False
003 32 10 23 26 26 31 12.314 58.114 True
004 22 13 1 28 19 25 16.438 41.418 True
005 9 7 9 6 8 4 1.182 20.102 False
我想创建一个新列,它是一个布尔列,这样我想遍历每个ID的所有周,如果任何值位于上限和下限列之外,我将其设置为等于True,否则为False。在这种情况下,上限和下限值是虚拟的,因此数据不会返回这些值。生成的列应与Problem
列
我知道这样做很难的方法是非常低效的
import pandas as pd
def Problem(df):
r = []
for i in range(len(df)):
res = []
x = [df['Week1'][i], df['Week2'][i], df['Week3'][i], df['Week4'][i], df['Week5'][i]]
for j in range (len(x)):
if (df['LowerBound'][i] <= x[j] <= df['UpperBound'][i]): res.append(True)
else: res.append(False)
if (False in res): r.append(True)
else: r.append(False)
return r
df['Problem'] = Problem(df)
这将有效,但它是漫长,艰难和低效的方式。我知道有df.apply可以为我做这个,但我不明白如何将我的特定功能转换为。有人可以帮忙吗?感谢
答案 0 :(得分:2)
您可以使用apply
更简洁地执行此操作,并调用between
来测试每行的值是否在范围内,使用~
反转结果并调用{{3}测试是否有任何正值:
In [24]:
df['Problem'] = df.apply(lambda x: ~x.loc['8-Jan':'12-Feb'].between(x['LowerBound'], x['UpperBound']), axis=1).any(axis=1)
df
Out[24]:
ID 8-Jan 15-Jan 22-Jan 29-Jan 5-Feb 12-Feb LowerBound UpperBound \
0 1 618 720 645 573 503 447 401.329 662.670
1 2 62 80 67 94 81 65 45.710 126.289
2 3 32 10 23 26 26 31 12.314 58.114
3 4 22 13 1 28 19 25 16.438 41.418
4 5 9 7 9 6 8 4 1.182 20.102
Problem
0 True
1 False
2 True
3 True
4 False
我们可以在这里看到各个步骤:
In [25]:
df.apply(lambda x: x.loc['8-Jan':'12-Feb'].between(x['LowerBound'], x['UpperBound']), axis=1)
Out[25]:
8-Jan 15-Jan 22-Jan 29-Jan 5-Feb 12-Feb
0 True False True True True True
1 True True True True True True
2 True False True True True True
3 True False False True True True
4 True True True True True True
使用~
反转掩码:
In [26]:
df.apply(lambda x: ~x.loc['8-Jan':'12-Feb'].between(x['LowerBound'], x['UpperBound']), axis=1)
Out[26]:
8-Jan 15-Jan 22-Jan 29-Jan 5-Feb 12-Feb
0 False True False False False False
1 False False False False False False
2 False True False False False False
3 False True True False False False
4 False False False False False False
现在使用any
测试是否有任何行值为正:
In [27]:
df.apply(lambda x: ~x.loc['8-Jan':'12-Feb'].between(x['LowerBound'], x['UpperBound']), axis=1).any(axis=1)
Out[27]:
0 True
1 False
2 True
3 True
4 False
dtype: bool