在 Python 中创建一个函数,用于根据多个条件从 pandas 数据帧值创建存储桶
Creating a function in Python for creating buckets from pandas dataframe values based on multiple conditions
我问了,它帮助了我,但现在我的任务更复杂了。
我的数据框有大约 100 列和 14 个尺度的值。
{'Diseasetype': {0: 'Oncology',
1: 'Oncology',
2: 'Oncology',
3: 'Nononcology',
4: 'Nononcology',
5: 'Nononcology'},
'Procedures1': {0: 100, 1: 300, 2: 500, 3: 200, 4: 400, 5: 1000},
'Procedures2': {0: 1, 1: 3, 2: 5, 3: 2, 4: 4, 5: 10},
'Procedures100': {0: 1000, 1: 3000, 2: 5000, 3: 2000, 4: 4000, 5: 10000}}
我想将数据帧每一列中的每个值转换为一个桶值。
我目前的解决方案是:
def encoding(col, labels):
return np.select([col<200, col.between(200,500), col.between(500,1000), col>1000], labels, 0)
onc_labels = [1,2,3,4]
nonc_labels = [11,22,33,44]
msk = df['Therapy_area'] == 'Oncology'
df[cols] = pd.concat((df.loc[msk, cols].apply(encoding, args=(onc_labels,)), df.loc[msk, cols].apply(encoding, args=(nonc_labels,)))).reset_index(drop=True)
它工作得很好,如果数据框的所有列都具有相同的比例,但它们不是。请记住,我有 14 个不同的比例。
我想更新上面的代码(或获得另一个解决方案),这将允许我存储数据。 我不能使用相同范围的值来分桶所有内容。
我的逻辑如下:
如果 Disease
== Oncology
和 Procedures1
在此范围内,将值转换为这些桶 (1, 2, 3)
如果 Disease
== Oncology
和 Procedures2
在此范围内,将值转换为这些桶 (1, 2, 3)
如果 Disease
!= Oncology
和 Procedures77
在此范围内,将值转换为这些桶 (4, 5, 6)
秤和水桶示例:
肿瘤学程序 1:< 200 = 1、200-400 = 2、>400 = 3
肿瘤学程序 2:< 2 = 1、2-4 = 2、>4 = 3
肿瘤学程序3:< 2000 = 1,2000-4000 = 2,>4000 = 3
非肿瘤学程序 1:< 200 = 4、200-400 = 5、>400 = 6
非肿瘤学程序 2:< 2 = 4、2-4 = 5、>4 = 6
非肿瘤学程序3:< 2000 = 4、2000-4000 = 5、>4000 = 6
预期输出(很高兴提供更多信息!)
Diseasetype Procedures1 Procedures2 Procedures100
Oncology 1 1 1
Oncology 2 2 2
Oncology 3 3 3
Nononcology 4 4 4
Nononcology 5 5 5
Nononcology 6 6 6
我使用了一个具有所有比例的帮助文件(来源在答案末尾):
使用 melt
展平您的数据框,然后使用 query
过滤掉您的行,最后使用 pivot
重塑您的数据框。您可以独立执行每一行以显示转换:
scales = pd.read_csv('scales.csv').fillna({'Start': -np.inf, 'End': np.inf})
out = (
df.melt('Diseasetype', var_name='Procedure', ignore_index=False).reset_index()
.merge(scales, on=['Diseasetype', 'Procedure'], how='left')
.query("value.between(Start, End)")
.pivot_table('Label', ['index', 'Diseasetype'], 'Procedure').astype(int)
.droplevel(0).rename_axis(columns=None).reset_index()
)
输出:
>>> df
Diseasetype Procedures1 Procedures100 Procedures2
0 Oncology 1 1 1
1 Oncology 2 2 2
2 Oncology 3 3 3
3 Nononcology 4 4 4
4 Nononcology 5 5 5
5 Nononcology 6 6 6
scales.csv
的内容:
Diseasetype,Procedure,Start,End,Label
Oncology,Procedures1,,200,1
Oncology,Procedures1,200,400,2
Oncology,Procedures1,400,,3
Oncology,Procedures2,,2,1
Oncology,Procedures2,2,4,2
Oncology,Procedures2,4,,3
Oncology,Procedures100,,2000,1
Oncology,Procedures100,2000,4000,2
Oncology,Procedures100,4000,,3
Nononcology,Procedures1,,200,4
Nononcology,Procedures1,200,400,5
Nononcology,Procedures1,400,,6
Nononcology,Procedures2,,2,4
Nononcology,Procedures2,2,4,5
Nononcology,Procedures2,4,,6
Nononcology,Procedures100,,2000,4
Nononcology,Procedures100,2000,4000,5
Nononcology,Procedures100,4000,,6
我问了
我的数据框有大约 100 列和 14 个尺度的值。
{'Diseasetype': {0: 'Oncology',
1: 'Oncology',
2: 'Oncology',
3: 'Nononcology',
4: 'Nononcology',
5: 'Nononcology'},
'Procedures1': {0: 100, 1: 300, 2: 500, 3: 200, 4: 400, 5: 1000},
'Procedures2': {0: 1, 1: 3, 2: 5, 3: 2, 4: 4, 5: 10},
'Procedures100': {0: 1000, 1: 3000, 2: 5000, 3: 2000, 4: 4000, 5: 10000}}
我想将数据帧每一列中的每个值转换为一个桶值。
我目前的解决方案是:
def encoding(col, labels):
return np.select([col<200, col.between(200,500), col.between(500,1000), col>1000], labels, 0)
onc_labels = [1,2,3,4]
nonc_labels = [11,22,33,44]
msk = df['Therapy_area'] == 'Oncology'
df[cols] = pd.concat((df.loc[msk, cols].apply(encoding, args=(onc_labels,)), df.loc[msk, cols].apply(encoding, args=(nonc_labels,)))).reset_index(drop=True)
它工作得很好,如果数据框的所有列都具有相同的比例,但它们不是。请记住,我有 14 个不同的比例。
我想更新上面的代码(或获得另一个解决方案),这将允许我存储数据。 我不能使用相同范围的值来分桶所有内容。
我的逻辑如下:
如果 Disease
== Oncology
和 Procedures1
在此范围内,将值转换为这些桶 (1, 2, 3)
如果 Disease
== Oncology
和 Procedures2
在此范围内,将值转换为这些桶 (1, 2, 3)
如果 Disease
!= Oncology
和 Procedures77
在此范围内,将值转换为这些桶 (4, 5, 6)
秤和水桶示例:
肿瘤学程序 1:< 200 = 1、200-400 = 2、>400 = 3
肿瘤学程序 2:< 2 = 1、2-4 = 2、>4 = 3
肿瘤学程序3:< 2000 = 1,2000-4000 = 2,>4000 = 3
非肿瘤学程序 1:< 200 = 4、200-400 = 5、>400 = 6
非肿瘤学程序 2:< 2 = 4、2-4 = 5、>4 = 6
非肿瘤学程序3:< 2000 = 4、2000-4000 = 5、>4000 = 6
预期输出(很高兴提供更多信息!)
Diseasetype Procedures1 Procedures2 Procedures100
Oncology 1 1 1
Oncology 2 2 2
Oncology 3 3 3
Nononcology 4 4 4
Nononcology 5 5 5
Nononcology 6 6 6
我使用了一个具有所有比例的帮助文件(来源在答案末尾):
使用 melt
展平您的数据框,然后使用 query
过滤掉您的行,最后使用 pivot
重塑您的数据框。您可以独立执行每一行以显示转换:
scales = pd.read_csv('scales.csv').fillna({'Start': -np.inf, 'End': np.inf})
out = (
df.melt('Diseasetype', var_name='Procedure', ignore_index=False).reset_index()
.merge(scales, on=['Diseasetype', 'Procedure'], how='left')
.query("value.between(Start, End)")
.pivot_table('Label', ['index', 'Diseasetype'], 'Procedure').astype(int)
.droplevel(0).rename_axis(columns=None).reset_index()
)
输出:
>>> df
Diseasetype Procedures1 Procedures100 Procedures2
0 Oncology 1 1 1
1 Oncology 2 2 2
2 Oncology 3 3 3
3 Nononcology 4 4 4
4 Nononcology 5 5 5
5 Nononcology 6 6 6
scales.csv
的内容:
Diseasetype,Procedure,Start,End,Label
Oncology,Procedures1,,200,1
Oncology,Procedures1,200,400,2
Oncology,Procedures1,400,,3
Oncology,Procedures2,,2,1
Oncology,Procedures2,2,4,2
Oncology,Procedures2,4,,3
Oncology,Procedures100,,2000,1
Oncology,Procedures100,2000,4000,2
Oncology,Procedures100,4000,,3
Nononcology,Procedures1,,200,4
Nononcology,Procedures1,200,400,5
Nononcology,Procedures1,400,,6
Nononcology,Procedures2,,2,4
Nononcology,Procedures2,2,4,5
Nononcology,Procedures2,4,,6
Nononcology,Procedures100,,2000,4
Nononcology,Procedures100,2000,4000,5
Nononcology,Procedures100,4000,,6