Python dataframe 检查列数据框中的值是否在另一个数据框中报告的值范围内
Python dataframe check if a value in a column dataframe is within a range of values reported in another dataframe
如果问题微不足道,我深表歉意,但作为一个 python 新手,我找不到正确的解决方案。
我有两个数据框,我需要向第一个数据框添加一列,如果第一个数据框的某个值介于第二个数据框的两个值之间,则该列为真,否则为假。
例如:
first_df = pd.DataFrame({'code1':[1,1,2,2,3,1,1],'code2':[10,22,15,15,7,130,2]})
second_df = pd.DataFrame({'code1':[1,1,2,2,3,1,1],'code2_start':[5,20,11,11,5,110,220],'code2_end':[15,25,20,20,10,120,230]})
first_df
code1 code2
0 1 10
1 1 22
2 2 15
3 2 15
4 3 7
5 1 130
6 1 2
second_df
code1 code2_end code2_start
0 1 15 5
1 1 25 20
2 2 20 11
3 2 20 11
4 3 10 5
5 1 120 110
6 1 230 220
对于第一个数据帧中的每一行,我应该检查 code2 列中报告的值是否在第二个数据帧的行标识的可能范围之一之间 second_df 例如:
在 first_df
code1=1
和 code2=22
的第 1 行
正在检查 second_df
我有 4 行 code1=1
、rows 0,1,5
和 6
,值 code2=22
在 [=26 标识的区间内=] 和 code2_end=25
所以函数应该 return True
.
考虑一个例子,其中函数应该 return False,
在 first_df
code1=1
和 code2=130
的第 5 行
但是 code1=1
中没有包含 130 的区间
我试过使用这个功能
def check(first_df,second_df):
for i in range(len(first_df):
return ((second_df.code2_start <= first_df.code2[i]) & (second_df.code2_end <= first_df.code2[i]) & (second_df.code1 == first_df.code1[i])).any()
并将其向量化
first_df['output'] = np.vectorize(check)(first_df, second_df)
但显然没有成功。
如果您能提供任何意见,我将很高兴。
谢谢。
A.
举个实际例子:
first_df.code1[0] = 1
因此我需要搜索 second_df 所有
的位置
second_df.code1 == first_df.code1[0]
0 True
1 True
2 False
3 False
4 False
5 True
6 True
对于状态为 True 的实例 0、1、5、6 我需要检查值是否
first_df.code2[0]
10
介于
确定的范围之一之间
second_df[second_df.code1 == first_df.code1[0]][['code2_start','code2_end']]
code2_start code2_end
0 5 15
1 20 25
5 110 120
6 220 230
由于 first_df.code2[0] 的值为 10,它介于 5 和 15 之间,因此第 0 行标识的范围因此我的函数应该 return 为真。在 first_df.code1[6] 的情况下,值仍然是 1,因此范围 table 仍然与上面相同,但 first_df.code2[6] 在这种情况下是 2 并且没有包含 2 的区间,因此结果应该为 False。
first_df['output'] = (second_df.code2_start <= first_df.code2) & (second_df.code2_end <= first_df.code2)
这是可行的,因为当您执行以下操作时:second_df.code2_start <= first_df.code2
你得到一个布尔系列。如果您随后对这些布尔系列中的两个执行逻辑与,您将得到一个具有值 True
的系列,其中两个系列均为 True
,否则为 False
。
这是一个例子:
>>> import pandas as pd
>>> a = pd.DataFrame([{1:2,2:4,3:6},{1:3,2:6,3:9},{1:4,2:8,3:10}])
>>> a['output'] = (a[2] <= a[3]) & (a[2] >= a[1])
>>> a
1 2 3 output
0 2 4 6 True
1 3 6 9 True
2 4 8 10 True
编辑:
所以根据你更新的问题和我对你问题的新解释,我会做这样的事情:
import pandas as pd
# Define some data to work with
df_1 = pd.DataFrame([{'c1':1,'c2':5},{'c1':1,'c2':10},{'c1':1,'c2':20},{'c1':2,'c2':8}])
df_2 = pd.DataFrame([{'c1':1,'start':3,'end':6},{'c1':1,'start':7,'end':15},{'c1':2,'start':5,'end':15}])
# Function checks if c2 value is within any range matching c1 value
def checkRange(x, code_range):
idx = code_range.c1 == x.c1
code_range = code_range.loc[idx]
check = (code_range.start <= x.c2) & (code_range.end >= x.c2)
return check.any()
# Apply the checkRange function to each row of the DataFrame
df_1['output'] = df_1.apply(lambda x: checkRange(x, df_2), axis=1)
我在这里做的是定义一个名为 checkRange
的函数,它将 x
、一行 df_1
和 code_range
作为输入,整个 df_2
数据框。它首先找到 code_range
中与给定行 x.c1
具有相同 c1
值的行。然后丢弃不匹配的行。这是在前两行中完成的:
idx = code_range.c1 == x.c1
code_range = code_range.loc[idx]
接下来,我们得到一个布尔系列,它告诉我们 x.c2
是否落在缩减的 code_range
DataFrame 中给出的任何范围内:
check = (code_range.start <= x.c2) & (code_range.end >= x.c2)
最后,因为我们只关心 x.c2
落在其中一个范围内,所以我们 return check.any()
的值。当我们在布尔系列上调用 any()
时,如果系列中的任何值是 True
.
,它将 return True
要在 df_1
的每一行上调用 checkRange
函数,我们可以使用 apply()
。我定义了一个 lambda expression 以便向 checkRange
函数发送行以及 df_2
。 axis=1
表示将在 DataFrame 的每一行(而不是每一列)上调用该函数。
如果问题微不足道,我深表歉意,但作为一个 python 新手,我找不到正确的解决方案。
我有两个数据框,我需要向第一个数据框添加一列,如果第一个数据框的某个值介于第二个数据框的两个值之间,则该列为真,否则为假。
例如:
first_df = pd.DataFrame({'code1':[1,1,2,2,3,1,1],'code2':[10,22,15,15,7,130,2]})
second_df = pd.DataFrame({'code1':[1,1,2,2,3,1,1],'code2_start':[5,20,11,11,5,110,220],'code2_end':[15,25,20,20,10,120,230]})
first_df
code1 code2
0 1 10
1 1 22
2 2 15
3 2 15
4 3 7
5 1 130
6 1 2
second_df
code1 code2_end code2_start
0 1 15 5
1 1 25 20
2 2 20 11
3 2 20 11
4 3 10 5
5 1 120 110
6 1 230 220
对于第一个数据帧中的每一行,我应该检查 code2 列中报告的值是否在第二个数据帧的行标识的可能范围之一之间 second_df 例如:
在 first_df
code1=1
和 code2=22
正在检查 second_df
我有 4 行 code1=1
、rows 0,1,5
和 6
,值 code2=22
在 [=26 标识的区间内=] 和 code2_end=25
所以函数应该 return True
.
考虑一个例子,其中函数应该 return False,
在 first_df
code1=1
和 code2=130
但是 code1=1
我试过使用这个功能
def check(first_df,second_df):
for i in range(len(first_df):
return ((second_df.code2_start <= first_df.code2[i]) & (second_df.code2_end <= first_df.code2[i]) & (second_df.code1 == first_df.code1[i])).any()
并将其向量化
first_df['output'] = np.vectorize(check)(first_df, second_df)
但显然没有成功。
如果您能提供任何意见,我将很高兴。
谢谢。
A.
举个实际例子:
first_df.code1[0] = 1
因此我需要搜索 second_df 所有
的位置second_df.code1 == first_df.code1[0]
0 True
1 True
2 False
3 False
4 False
5 True
6 True
对于状态为 True 的实例 0、1、5、6 我需要检查值是否
first_df.code2[0]
10
介于
确定的范围之一之间second_df[second_df.code1 == first_df.code1[0]][['code2_start','code2_end']]
code2_start code2_end
0 5 15
1 20 25
5 110 120
6 220 230
由于 first_df.code2[0] 的值为 10,它介于 5 和 15 之间,因此第 0 行标识的范围因此我的函数应该 return 为真。在 first_df.code1[6] 的情况下,值仍然是 1,因此范围 table 仍然与上面相同,但 first_df.code2[6] 在这种情况下是 2 并且没有包含 2 的区间,因此结果应该为 False。
first_df['output'] = (second_df.code2_start <= first_df.code2) & (second_df.code2_end <= first_df.code2)
这是可行的,因为当您执行以下操作时:second_df.code2_start <= first_df.code2
你得到一个布尔系列。如果您随后对这些布尔系列中的两个执行逻辑与,您将得到一个具有值 True
的系列,其中两个系列均为 True
,否则为 False
。
这是一个例子:
>>> import pandas as pd
>>> a = pd.DataFrame([{1:2,2:4,3:6},{1:3,2:6,3:9},{1:4,2:8,3:10}])
>>> a['output'] = (a[2] <= a[3]) & (a[2] >= a[1])
>>> a
1 2 3 output
0 2 4 6 True
1 3 6 9 True
2 4 8 10 True
编辑:
所以根据你更新的问题和我对你问题的新解释,我会做这样的事情:
import pandas as pd
# Define some data to work with
df_1 = pd.DataFrame([{'c1':1,'c2':5},{'c1':1,'c2':10},{'c1':1,'c2':20},{'c1':2,'c2':8}])
df_2 = pd.DataFrame([{'c1':1,'start':3,'end':6},{'c1':1,'start':7,'end':15},{'c1':2,'start':5,'end':15}])
# Function checks if c2 value is within any range matching c1 value
def checkRange(x, code_range):
idx = code_range.c1 == x.c1
code_range = code_range.loc[idx]
check = (code_range.start <= x.c2) & (code_range.end >= x.c2)
return check.any()
# Apply the checkRange function to each row of the DataFrame
df_1['output'] = df_1.apply(lambda x: checkRange(x, df_2), axis=1)
我在这里做的是定义一个名为 checkRange
的函数,它将 x
、一行 df_1
和 code_range
作为输入,整个 df_2
数据框。它首先找到 code_range
中与给定行 x.c1
具有相同 c1
值的行。然后丢弃不匹配的行。这是在前两行中完成的:
idx = code_range.c1 == x.c1
code_range = code_range.loc[idx]
接下来,我们得到一个布尔系列,它告诉我们 x.c2
是否落在缩减的 code_range
DataFrame 中给出的任何范围内:
check = (code_range.start <= x.c2) & (code_range.end >= x.c2)
最后,因为我们只关心 x.c2
落在其中一个范围内,所以我们 return check.any()
的值。当我们在布尔系列上调用 any()
时,如果系列中的任何值是 True
.
True
要在 df_1
的每一行上调用 checkRange
函数,我们可以使用 apply()
。我定义了一个 lambda expression 以便向 checkRange
函数发送行以及 df_2
。 axis=1
表示将在 DataFrame 的每一行(而不是每一列)上调用该函数。