首页 > 解决方案 > 根据另一列的条件修改列中的值

问题描述

问题:如何df根据变量对 a 进行分组,使用for循环进行计算?

任务是根据列中的值进行条件计算。但是计算常数取决于参考列中的值。鉴于此df

In [55]: df = pd.DataFrame({
    ...:     'col1' : ['A', 'A', 'B', np.nan, 'D', 'C'],
    ...:     'col2' : [2, 1, 9, 8, 7, 4],
    ...:     'col3': [0, 1, 9, 4, 2, 3],
    ...: })

In [56]: df
Out[56]: 
  col1  col2  col3
0    A     2     0
1    A     1     1
2    B     9     9
3  NaN     8     4
4    D     7     2
5    C     4     3

我在这里使用了解决方案来插入一'math'列,该列从余额中col3添加 10。但现在我想遍历一个列表以设置取决于col1. 结果如下:

In [57]: items = ['A', 'D']

In [58]: for item in items:
    ...:     df.loc[:, 'math'] = df.loc[df['col1'] == item, 'col3']
    ...:     

In [59]: df
Out[59]: 
  col1  col2  col3  math
0    A     2     0   NaN
1    A     1     1   NaN
2    B     9     9   NaN
3  NaN     8     4   NaN
4    D     7     2   2.0
5    C     4     3   NaN

明显的问题是 df 在每次迭代时都会被覆盖。索引 0 和 1的math列在第一次迭代中计算值,但在第二次迭代中被删除。结果df仅考虑列表的最后一个元素。

我可以通过并添加编码来迭代每个索引值——但这似乎比 pythonic 更可悲。

.mul()示例的预期输出

In [100]: df
Out[100]: 
  col1  col2  col3  math
0    A     2     0   0.0
1    A     1     1  10.0
2    B     9     9   NaN
3  NaN     8     4   NaN
4    D     7     2  20.0
5    C     4     3   NaN

标签: pythonpandasdataframe

解决方案


您当前方法的问题是每次后续迭代的输出都会覆盖之前迭代的输出。所以你最终会得到最后一项的输出,仅此而已。

选择所有包含元素的行items并进行分配,就像您之前所做的一样。

df['math'] = df.loc[df.col1.isin(items), 'col3'] * 10

或者,

df['math'] = df.query("col1 in @items").col3 * 10

甚至,

df['math'] = df.col3.where(df.col1.isin(items)) * 10

df

  col1  col2  col3  math
0    A     2     0   0.0
1    A     1     1  10.0
2    B     9     9   NaN
3  NaN     8     4   NaN
4    D     7     2  20.0
5    C     4     3   NaN

推荐阅读