#python-3.x #pandas
Вопрос:
Поискал здесь несколько тем в поисках ответа, но ничего похожего на то, что я собираюсь сделать. Я пытаюсь создать логический столбец в кадре данных, где один из параметров основан на металле и максимуме связанных затрат, см. Ниже.
Cost_ranges = {'Metals': ["Cu", "Pb", "Zn", "Ni", "Mo", "Co", "Sn", "U3O8", "Ag", "Au", "Pt", "Pd", "Rh", "Os", "Ru", "Ir"],
'Cost Maximum': [350, 200, 200, 500, 800, 1000, 250, 2500, 30, 2500, 500, 1000, 6000, 2500, 2500, 2500]}
Диктант используется для заполнения приведенной ниже формулы:
df_Cost['Total Cost'] >= Cost_ranges['Cost Maximum']
т. е. df_Cost[«Металл»] содержит значение «Cu», он вызывает «Максимальную стоимость» 350 из dict и использует это для логического выражения, следовательно, формула будет гласить:
df_Cost[Total Cost] >= 350
Мне нужно, чтобы это применялось ко всем строкам в фрейме данных. Я использую df.eval (), но мне нужен дополнительный уровень обработки, чтобы соответствовать правильному пределу на металл.
Я пробовал использовать df.eval(), df.query(), df.loc и df.apply (), но продолжаю получать «Ошибку типа:» Объекты серии изменчивы, поэтому их нельзя хэшировать » или » Ошибка значения: («Длины должны совпадать для сравнения’, (9999,), (16,))’ для каждого решения.
С нетерпением ждем ответов.
Ответ №1:
В зависимости от ваших фактических данных вы можете сделать что-то вроде:
import numpy as np
import pandas as pd
Cost_ranges = {'Metals': ["Cu", "Pb", "Zn", "Ni", "Mo", "Co", "Sn", "U3O8", "Ag", "Au", "Pt", "Pd", "Rh", "Os", "Ru", "Ir"],
'Cost Maximum': [350, 200, 200, 500, 800, 1000, 250, 2500, 30, 2500, 500, 1000, 6000, 2500, 2500, 2500]}
N = 20
d = pd.DataFrame({'Metals': np.random.choice(["Cu", "Pb", "Zn", "Ni"], N),
'Cost': np.random.random(N) * 1000})
d.merge(pd.DataFrame(Cost_ranges).astype({'Cost Maximum': float}),
on = "Metals", how = "left")
.eval('want = Cost > `Cost Maximum`')
# Metals Cost Cost Maximum want
# 0 Cu 297.386007 350.0 False
# 1 Pb 55.570657 200.0 False
# 2 Pb 91.803336 200.0 False
# 3 Cu 916.273995 350.0 True
# 4 Zn 796.383326 200.0 True
# 5 Pb 112.504581 200.0 False
Ответ №2:
Предполагая, что вы df_Cost
выглядите немного так (с потенциально большим количеством строк и столбцов):
>>> df_Cost
Total Cost Metal
0 315 Cu
1 420 Cu
Самый простой способ-использовать словарь для перевода с металла на максимальную стоимость. Затем вам нужно внести Cost_ranges
в словарь сопоставление имени металла с ценой:
>>> cost_lookup = dict(zip(Cost_ranges['Metals'], Cost_ranges['Cost Maximum']))
>>> cost_lookup
{'Cu': 350, 'Pb': 200, 'Zn': 200, 'Ni': 500, 'Mo': 800, 'Co': 1000, 'Sn': 250, 'U3O8': 2500, 'Ag': 30, 'Au': 2500, 'Pt': 500, 'Pd': 1000, 'Rh': 6000, 'Os': 2500, 'Ru': 2500, 'Ir': 2500}
>>> df_Cost['Metal'].map(cost_lookup)
0 350
1 350
Name: Metal, dtype: int64
>>> df_Cost['Total Cost'] >= df_Cost['Metal'].map(cost_lookup)
0 False
1 True
dtype: bool