根据另一个条件修改列中的值

时间:2018-06-27 03:45:37

标签: python pandas dataframe

问题:如何基于变量对df进行分组,如何使用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

我已使用解决方案here插入一个'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

2 个答案:

答案 0 :(得分:3)

当前方法的问题在于,每个后续迭代的输出都会覆盖之前迭代的输出。因此,您最终只会获得最后一项的输出,仅此而已。

与以前一样,选择所有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

答案 1 :(得分:2)

分配失败的原因是,在每个for循环中都为您分配了一个具有新值的Math,如下所示,它将仅显示最后一个并在for循环后显示给结果

0     0.0
1    10.0
2     NaN
3     NaN
4     NaN
5     NaN
Name: col3, dtype: float64
0     NaN
1     NaN
2     NaN
3     NaN
4    20.0
5     NaN
Name: col3, dtype: float64

您可以使用下面的

df.loc[df.col1.isin(items),'math']=df.col3*10
df
Out[85]: 
  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