给定一个包含两列的数据帧来描述记录类型及其所处的阶段,根据阶段和类型将唯一值赋给新列的最典型的方法是什么?例如:

d = {'type': ['a','b','c','a','b','c','a','b','c',], 'phase': [-10,3,2,1,-7,-3,-1,-5,4]}
df_ = pd.DataFrame(data=d)
df_

enter image description here

具有上下限的人为示例映射:

a_phase = {
('<', -9):0.001,
-9:0.010,
-8:0.022,
-7:0.026,
-6:0.092,
-5:0.091,
-4:0.082,
-3:0.121,
-2:0.060,
-1:0.105,
0:0.018,
1:0.092,
2:0.092,
3:0.092,
4:0.092,
('>',4):0.000,
}

b_phase = {
('<', -9):0.016,
-9:0.011,
-8:0.021,
-7:0.028,
-6:0.052,
-5:0.075,
-4:0.057,
-3:0.102,
-2:0.238,
-1:0.270,
0:0.034,
1:0.014,
2:0.061,
('>',2):0.000,
}

c_phase = {
('<', -9):0.016,
-9:0.016,
-8:0.011,
-7:0.010,
-6:0.038,
-5:0.015,
-4:0.099,
-3:0.117,
-2:0.216,
-1:0.213,
0:0.008,
1:0.008,
2:0.008,
('>',2):0.000,
}

我可以只使用一堆np.where个条款,但这感觉非常低效,所以我想联系社区,看看是否有人有建议.我还意识到,我不能在我的字典映射中使用逻辑运算符><作为键,这仅用于表示目的.

理想的输出应该如下所示:

enter image description here

推荐答案

一种 Select 可能是建立一个嵌套的字典,并映射每个组的值,最终使用cut来限制范围.如果你有很多词典,效率可能不会很高.

如果您稍微更改一下字典,另一个 Select 是创建一个DataFrame并使用merge_asof:


Inf = float('inf')

a_phase = {
-Inf:0.001,
-9:0.010,
-8:0.022,
-7:0.026,
-6:0.092,
-5:0.091,
-4:0.082,
-3:0.121,
-2:0.060,
-1:0.105,
0:0.018,
1:0.092,
2:0.092,
3:0.092,
4:0.092,
4.1:0.000,
}
b_phase = {
-Inf:0.016,
-9:0.011,
-8:0.021,
-7:0.028,
-6:0.052,
-5:0.075,
-4:0.057,
-3:0.102,
-2:0.238,
-1:0.270,
0:0.034,
1:0.014,
2:0.061,
2.1:0.000,
}
c_phase = {
-Inf:0.016,
-9:0.016,
-8:0.011,
-7:0.010,
-6:0.038,
-5:0.015,
-4:0.099,
-3:0.117,
-2:0.216,
-1:0.213,
0:0.008,
1:0.008,
2:0.008,
2.1:0.000,
}

ref = (pd.DataFrame({'a': a_phase, 'b': b_phase, 'c': c_phase})
         .melt(var_name='type', value_name='weight', ignore_index=False)
         .rename_axis('phase').reset_index()
         .sort_values(by='phase')
         .dropna(subset='weight')
       )

out = (pd.merge_asof(df_.reset_index()
                        .astype({'phase': 'float64'})
                        .sort_values(by='phase'),
                     ref, by='type', on='phase')#, direction='forward')
         .set_index('index').reindex(df_.index)
       )

输出:

  type  phase  weight
0    a  -10.0   0.001
1    b    3.0   0.000
2    c    2.0   0.008
3    a    1.0   0.092
4    b   -7.0   0.028
5    c   -3.0   0.117
6    a   -1.0   0.105
7    b   -5.0   0.075
8    c    4.0   0.000

Python-3.x相关问答推荐

如何在Python Matplotlib中在x轴上放置点

将值从函数传递到标签

无法理解此递归函数的分配和环境用法

为什么 mypy 不适用于 sqlalchemy?

如何在两个矩阵的比较中允许任何列的符号差异,Python3?

通过最接近的匹配合并两个不同长度的列上的两个数据框

Pandas数据单调行为

判断是否存在大文件而不下载它

TimescaleDB:是否可以从 Python 调用create_hypertable?

numpy.ndarray 与 pandas.DataFrame

使用逗号时,除了处理程序中的语法无效

使用 Sublime Text 3 在 Python 3 中打印 UTF-8

如何配置 Atom 以运行 Python3 脚本?

登录csv文件的正确方法是什么?

在没有时间的python中创建日期

为什么在 Python 3 中实例的 __dict__ 的大小要小得多?

使用完整路径激活 conda 环境

使用 python 3.0 的 Numpy

如何阻止散景在 Jupyter Notebook 中打开新标签?

十六进制字符串到 Python 3.2 中的带符号整数?