问题:如何基于变量对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
答案 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