Python 数据框列值与列表中的元素数字比较

Python 数据框列值与列表中的元素数字比较,python,pandas,dataframe,numpy,Python,Pandas,Dataframe,Numpy,我有3个多索引列数据帧 数据帧1(最小值): 数据帧2(用于与比较的值) 第0行、第1行和第2行是相同的,我将数据帧扩展到三行,以便与最小和最大数据帧进行比较。每个数据帧单元中的值都是ndarray | A | B | C | | Val | Val | Val | |-----

我有3个多索引列数据帧

数据帧1(最小值):

数据帧2(用于与比较的值)

第0行、第1行和第2行是相同的,我将数据帧扩展到三行,以便与最小和最大数据帧进行比较。每个数据帧单元中的值都是ndarray

  |          A          |           B           |          C         |
  |         Val         |          Val          |         Val        |
  |---------------------|-----------------------|--------------------|
0 | [27.58,28.37,28.73] | [17.31, 18.42, 18.72] | [1.36, 1.28, 1.27] |
1 | [27.58,28.37,28.73] | [17.31, 18.42, 18.72] | [1.36, 1.28, 1.27] |
2 | [27.58,28.37,28.73] | [17.31, 18.42, 18.72] | [1.36, 1.28, 1.27] |
数据帧3(最大值):

预期结果:

  |          A          |           B           |          C           |
  |        Result       |          Result       |         Result       |
  |---------------------|-----------------------|----------------------|
0 | [True, True, False] |  [True, True, False]  | [True, True, True]   |
1 | [True, True, True]  | [True, False, False]  | [True, False, False] |
2 | [True, True, True]  | [False, False, False] | [True, True, False]  |
我希望通过以下方式执行元素级比较:

min <= each element in ndarray <= max

如果您有如下数据帧:

df1 = pd.DataFrame({'AMin': {0: 26.47, 1: 27.23, 2: 27.23},
 'BMin': {0: 17.31, 1: 14.38, 2: 18.88},
 'CMin': {0: 1.26, 1: 1.36, 2: 1.28}})


df2 = pd.DataFrame({'AVal': {0: [27.58, 28.37, 28.73],
  1: [27.58, 28.37, 28.73],
  2: [27.58, 28.37, 28.73]},
 'BVal': {0: [17.31, 18.42, 18.72],
  1: [17.31, 18.42, 18.72],
  2: [17.31, 18.42, 18.72]},
 'CVal': {0: [1.36, 1.28, 1.27], 1: [1.36, 1.28, 1.27], 2: [1.36, 1.28, 1.27]}})

df3 = pd.DataFrame({'AMax': {0: 28.68, 1: 29.5, 2: 29.87},
 'BMax': {0: 18.42, 1: 17.31, 2: 20.45},
 'CMax': {0: 1.37, 1: 1.47, 2: 1.39}})
然后,您可以分解第二个数据帧并比较这些值

m = df2.apply(pd.Series.explode).values
df = pd.DataFrame(
    (df1.iloc[np.arange(len(df1)).repeat(3)].values <= m) &
    (m <= df3.iloc[np.arange(len(df3)).repeat(3)].values),
    columns=df2.columns
)

df = df.groupby(df.index // 3).agg(list)

只需将列值转换为NumPy数组。并简单地将其视为数组比较问题(按行)

您可以使用
apply

def bool_check(row):
    col = row.name[0]
    min_val = df1[pd.IndexSlice[col]].to_numpy()
    max_val = df3[pd.IndexSlice[col]].to_numpy()
    x = np.array(row.tolist())
    return list((x >= min_val) & (x <= max_val))

res:

A. B C 结果 结果 结果 0 [对,对,错] [对,对,错] [真的,真的,真的] 1. [真的,真的,真的] [真,假,假] [真,假,假] 2. [真的,真的,真的] [假,假,假] [对,对,错]
请在本例中发布用于生成数据帧的代码。您好,欢迎使用SO。我们是来帮忙的,但我们的时间是宝贵的,所以我建议你花点时间休息一下。得到答案的机会要比没有答案的机会高得多。如果你还没有完成,请阅读。除此之外,我还建议你好好回答你的问题,把所有的信息都放在你的问题中。旁注:在你的数据框中保存列表/数组通常是不好的做法。这会阻止使用pandas api的完整表达式,产生性能较差的操作,通常会使事情变得更复杂。@anon01因为我想比较列表中每个元素的最大值和最小值的不同组合,所以我必须将要比较的元素分组到列表中,并将不同的最小值和最大值放在不同的数据帧中。我是python新手,不确定是否有有效的垂直化方法来实现这一点,尽管我知道
apply
函数性能不是很好。多次使用apply会使代码非常慢。@Pygirl这就是我添加2个选项的原因。第一个没有
应用
。与您的答案相比,它仍然很慢:)@Pygirl对第一个选项做了一些更改。如果你不介意的话,你能比较一下更新后的选项的性能吗。你是想救我吗P使用
df2.apply(pd.Series.explode)
两次:PNope.:P修好了!!。谢谢^-^@Pygirl
min_columns = pd.MultiIndex.from_product( [ [ 'A', 'B', 'C' ], [ 'Min' ] ] )
val_columns = pd.MultiIndex.from_product( [ [ 'A', 'B', 'C' ], [ 'Val' ] ] )
max_columns = pd.MultiIndex.from_product( [ [ 'A', 'B', 'C' ], [ 'Max' ] ] )

min_df = pd.DataFrame( [ [ 26.47, 17.31, 1.26 ], [ 27.23, 14.38, 1.36 ], [ 27.23, 18.88, 1.28 ] ], columns=min_columns )
val_df = pd.DataFrame( [ [ [ 27.58, 28.37, 28.73 ], [ 17.31, 18.42, 18.72], [1.36, 1.28, 1.27 ] ] ] , columns=val_columns )
max_df = pd.DataFrame( [ [ 28.68, 18.42, 1.37 ], [ 29.50, 17.31, 1.47 ], [ 29.87, 20.45, 1.39 ] ] , columns=max_columns )
df1 = pd.DataFrame({'AMin': {0: 26.47, 1: 27.23, 2: 27.23},
 'BMin': {0: 17.31, 1: 14.38, 2: 18.88},
 'CMin': {0: 1.26, 1: 1.36, 2: 1.28}})


df2 = pd.DataFrame({'AVal': {0: [27.58, 28.37, 28.73],
  1: [27.58, 28.37, 28.73],
  2: [27.58, 28.37, 28.73]},
 'BVal': {0: [17.31, 18.42, 18.72],
  1: [17.31, 18.42, 18.72],
  2: [17.31, 18.42, 18.72]},
 'CVal': {0: [1.36, 1.28, 1.27], 1: [1.36, 1.28, 1.27], 2: [1.36, 1.28, 1.27]}})

df3 = pd.DataFrame({'AMax': {0: 28.68, 1: 29.5, 2: 29.87},
 'BMax': {0: 18.42, 1: 17.31, 2: 20.45},
 'CMax': {0: 1.37, 1: 1.47, 2: 1.39}})
m = df2.apply(pd.Series.explode).values
df = pd.DataFrame(
    (df1.iloc[np.arange(len(df1)).repeat(3)].values <= m) &
    (m <= df3.iloc[np.arange(len(df3)).repeat(3)].values),
    columns=df2.columns
)

df = df.groupby(df.index // 3).agg(list)
                     A                      B                     C
0  [True, True, False]    [True, True, False]    [True, True, True]
1   [True, True, True]   [True, False, False]  [True, False, False]
2   [True, True, True]  [False, False, False]   [True, True, False]
def bool_check(row):
    col = row.name[0]
    min_val = df1[pd.IndexSlice[col]].to_numpy()
    max_val = df3[pd.IndexSlice[col]].to_numpy()
    x = np.array(row.tolist())
    return list((x >= min_val) & (x <= max_val))
res = df2.apply(bool_check,axis=0).rename(columns={'Val':'Result'})