猿问

根据多列中的值创建新的数据框列

仅供参考,性能/速度对于这个问题并不重要。


我有一个名为cost_table...的现有熊猫数据框


+----------+---------+------+-------------------------+-----------------+

| material | percent | qty  | price_control_indicator | acct_assign_cat |

+----------+---------+------+-------------------------+-----------------+

| abc111   | 1.00    |   50 | v                       | #               |

| abc222   | 0.25    | 2000 | s                       | #               |

| xyz789   | 0.45    |    0 | v                       | m               |

| def456   | 0.9     |    0 | v                       | #               |

| 123xyz   | 0.2     |    0 | v                       | m               |

| lmo888   | 0.6     |    0 | v                       | m               |

+----------+---------+------+-------------------------+-----------------+

我需要cost_source根据多个字段中的值添加一个字段。


google 上出现的大多数答案都涉及列表推导式或三元运算符,但那些仅包含基于一列中的值的逻辑。例如,


cost_table['cost_source'] = ['map' if qty > 0 else None for qty in cost_table['qty']]


这基于一列中的值起作用,但我不知道如何扩展它以包含多列中的逻辑(或者甚至可能?)。它似乎也不是一个非常可读/可维护的解决方案。


我尝试使用for in带有if elif语句的循环,但 in 的值cost_table['cost_source']保持不变并且适用None于所有行。但是,如果我在循环中打印每一行,则row['cost_source']具有所需的值。


d = {

  'material': ['abc111', 'abc222', 'xyz789', 'def456', '123xyz', 'lmo888'],

  'percent': [1, .25, .45, .9, .2, .6],

  'qty': [50, 2000, 0, 0, 0, 0],

  'price_control_indicator': ['v', 's','v', 'v', 'v', 'v'],

  'acct_assign_cat': ['#', '#', 'm', '#', 'm', 'm']

}


cost_table = pd.DataFrame(data=d)


cost_table['cost_source'] = None


for index, row in cost_table.iterrows():

  if (row['qty'] > 0) or (row['price_control_indicator'] == "s") or (row['acct_assign_cat'] == "#"):

    row['cost_source'] = "map"

  elif (row['percent'] >= 40) and (row['acct_assign_cat'] == "m"):

    row['cost_source'] = "vendor"

  else:

    row['cost_source'] = None


  print(row['cost_source']) # outputs map, vendor, or None as expected


print(cost_table)

哪个输出...



哔哔one
浏览 193回答 2
2回答

catspeake

使用df.apply(lambda x: fun(x), 但带有参数axis=1,因此 lambda 函数逐行应用(默认为逐列)。d = {  'material': ['abc111', 'abc222', 'xyz789', 'def456', '123xyz', 'lmo888'],  'percent': [100, 25, 45, 90, 20, 60],  'qty': [50, 2000, 0, 0, 0, 0],  'price_control_indicator': ['v', 's','v', 'v', 'v', 'v'],  'acct_assign_cat': ['#', '#', 'm', '#', 'm', 'm']}cost_table = pd.DataFrame(data=d)def process_row(row):    if (row['qty'] > 0) or (row['price_control_indicator'] == "s") or (row['acct_assign_cat'] == "#"):        return "map"    elif (row['percent'] >= 40) and (row['acct_assign_cat'] == "m"):        return "vendor"    else:        return Nonecost_table['cost_source'] = cost_table.apply(lambda row: process_row(row), axis=1)print(cost_table)(我还纠正了一个不一致的地方:在数据procents中大概应该乘以 100)

30秒到达战场

如果您想使用 np.selectcond1 = cost_table.qty.gt(0) | cost_table.price_control_indicator.eq('s') | cost_table.acct_assign_cat.eq('#')cond2 = cost_table.percent.ge(0.4) & cost_table.acct_assign_cat.eq('m')cost_table['cost_source'] = np.select([cond1, cond2], ['map', 'vendor'], default='None')print(cost_table)  material  percent   qty price_control_indicator acct_assign_cat cost_source0   abc111     1.00    50                       v               #         map1   abc222     0.25  2000                       s               #         map2   xyz789     0.45     0                       v               m      vendor3   def456     0.90     0                       v               #         map4   123xyz     0.20     0                       v               m        None5   lmo888     0.60     0                       v               m      vendor
随时随地看视频慕课网APP

相关分类

Python
我要回答