我试图根据连续值所处的范围,将一列连续浮点值映射为一些离散(带扣)值

例如

df_lookup = pd.DataFrame(data=[[0.0, 0.3, 10.1],
                               [0.3, 0.65, 30.3],
                               [0.65, 1.0, 50.5]], 
                        columns=['start', 'end', 'mapped_value'])
# create intervals
df_lookup['interval'] = df_lookup.apply(lambda x: 
                                             pd.Interval(x['start'], 
                                                         x['end'], 
                                                         closed='both' if x['end']==1.0 else 'left'), axis=1)

df_lookup

输出:

start end mapped_value interval
0 0.00 0.30 10.1 [0.0, 0.3)
1 0.30 0.65 30.3 [0.3, 0.65)
2 0.65 1.00 50.5 [0.65, 1.0]
df_data=pd.DataFrame(data=[['A', 0.3],
                           ['B', 0.65],
                           ['C', 0.6],
                           ['D', 0.75],
                           ['E', 0.4]], 
                     columns=['ID', 'original_value'])
df_data
ID original_value
0 A 0.30
1 B 0.65
2 C 0.60
3 D 0.75
4 E 0.40

此时,我使用pandas.DataFrame.apply获得查找值,但

df_data['mapped_value'] = df_data.apply(
        lambda x: df_lookup.loc[x['original_value'] in df_lookup['interval']]['mapped_value'], 
            axis=1)

但这告诉我KeyError: 'False: boolean label can not be used without a boolean index'

Further investigation shows me that the issue I have is that when I do the in I just get a single boolean value returned not a list of booleans, 例如, for data ID='A' where the original value is 0.3, I am hoping that x['original_value'] in df_lookup['interval'] would return [False, True, False] but in fact its returning False

我很想在这里了解一下如何实现这种"查找"映射.谢谢

推荐答案

如果间隔可能不相交,则可以使用pandas.merge_asof并在上限上进行可选判断:

df_data['mapped_value'] = (pd
 .merge_asof(df_data.sort_values(by='original_value'),
             df_lookup,
             left_on='original_value', right_on='start')
 # assign command below is only required if the intervals are disjoint
 .assign(mapped_value=lambda d: d['mapped_value']
                                .mask(d['end'].lt(d['original_value'])))
 ['mapped_value']
)

输出:

  ID  original_value  mapped_value
0  A            0.30          30.3
1  B            0.65          30.3
2  C            0.60          30.3
3  D            0.75          50.5
4  E            0.40          50.5

Python相关问答推荐

用ctype构建指针链

使用Python Cerberus初始化一个循环数据 struct (例如树)(v1.3.5)

剧作家Python:expect(locator).to_be_visible()vs locator.wait_for()

通过优化空间在Python中的饼图中添加标签

使用SciPy进行曲线匹配未能给出正确的匹配

如何将ctyles.POINTER(ctyles.c_float)转换为int?

使用新的类型语法正确注释ParamSecdecorator (3.12)

韦尔福德方差与Numpy方差不同

在Python中处理大量CSV文件中的数据

如何标记Spacy中不包含特定符号的单词?

管道冻结和管道卸载

Python—从np.array中 Select 复杂的列子集

梯度下降:简化要素集的运行时间比原始要素集长

Python脚本使用蓝牙运行在Windows 11与raspberry pi4

使用Python从URL下载Excel文件

名为__main__. py的Python模块在导入时不运行'

从Windows Python脚本在WSL上运行Linux应用程序

pandas:对多级列框架的列进行排序/重新排序

具有相同图例 colored颜色 和标签的堆叠子图

交替字符串位置的正则表达式