Pandas:如何使用另一列列出一列中存在的起始值和结束值之间的数字?

标签 pandas dataframe

我有以下数据框,其中包含与列设置相对应的值 -

import pandas as pd

data_0 = {'setting':[0,0,0,0,1,1,1,2,2,2,2,2,2],
        'values': [0, 1, 2, 3, 0, 1, 2, 0,1,2,3, 5,6]
        }

df_0 = pd.DataFrame(data_0)

我有另一个数据框,其中包含每个设置的相关开始值和结束值 -

data_1 = {'setting':[0,1,2,2],
        'start_value': [1,0,1,3],
        'end_value':[3,2,3,6]
        }
df_1 = pd.DataFrame(data_1)

现在,我想根据 df_1 中的 start_value 和 end_value 从 df_0 中提取值。

最终输出应如下所示 -

data_2 = {'setting':[0,0,1,1,2,2,2,2],
        'start_value': [1,1,0,0,1,1,3,3],
        'end_value':[3,3,2,2,3,3,6,6],
        'values_from_data_0':[1,2,0,1,1,2,3,5]
        }
df_2 = pd.DataFrame(data_2)
   setting  start_value  end_value  values_from_data_0
0        0            1          3                   1
1        0            1          3                   2
2        1            0          2                   0
3        1            0          2                   1
4        2            1          3                   1
5        2            1          3                   2
6        2            3          6                   3
7        2            3          6                   5

请注意 setting = 2 列对应的缺失值 4。

这是我天真的(也是错误的)尝试 -

import numpy as np
list_final = []
for index, row in df_1.iterrows():

    value_start = row['start_value']
    value_end = row['end_value']
    assert value_start<value_end

    values = np.arange(value_start, value_end)
    list_final.append(values)

df_1["values_from_data_0"] = list_final
df_1 = df_1.explode('values_from_data_0')

print(df_1)

这几乎是正确的。但是,由于它没有从 df_0 获取值,而是使用 arange,因此结果是错误的。

最佳答案

假设设置中的间隔不重叠,您需要使用 merge_asof :

out = (pd.merge_asof(df_0.reset_index().sort_values(by='values'),
                     df_1.sort_values(by='start_value'),
                     by='setting', left_on='values', right_on='start_value')
         .query('values < end_value')
         .set_index('index').sort_index()
         .rename(columns={'values': 'values_from_data_0'})
      )

或者,使用 janitorconditional_join :

# pip install pyjanitor
import janitor

out = (df_0.conditional_join(df_1, 
                             ('setting', 'setting', '=='),
                             ('values', 'start_value', '>='),
                             ('values', 'end_value', '<'),
                             df_columns = {'values': 'values_from_data_0'}
                            )
      )

输出:

   values_from_data_0  setting  start_value  end_value
0                   1        0            1          3
1                   2        0            1          3
2                   0        1            0          2
3                   1        1            0          2
4                   1        2            1          3
5                   2        2            1          3
6                   3        2            3          6
7                   5        2            3          6

关于Pandas:如何使用另一列列出一列中存在的起始值和结束值之间的数字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77380147/

相关文章:

python - Pandas 相当于 data.table

python - Pandas:根据现有列将列添加到 DataFrame

python - 如何在 Python Dask 数据帧中执行位置索引

r - 根据给定的顺序对数据框进行排序

python - 根据另一列填充 pandas 列

python - Python pandas 读取文件时出现日期解析错误

python - 使用 pd.concat() 时,生成的数据框列名称出现在括号中并添加逗号

file - 是否可以使用 Pandas 的 read_csv 读取分类列?

python - 如何防止plotly.figure_factory.create_table将整数转换为浮点值?

r - 数据框中行名称的交集(数据子集)?