最近在做批量数据分析,利用pandas的DataFrame时,有一个需求,需要根据一列的取值进行判断,然后将python运行的状态信息写入另一列。结果发现多次写入均不成功。然后开始各种搜索,并没有找到合适的答案。其中一篇较为接近的文章是遇到我类似的问题,但下面并没给出合理的解决办法。(原文地址:https://ask.csdn.net/questions/773703)
几经辗转,将结果办法记录如下。
原始问题重现:
import numpy as np
import pandas as pd
df = pd.DataFrame(np.random.rand(10, 2), columns=list('ab'))
print(df)
df['a'] = 1
print(df)
运行结果:
a b
0 0.275576 0.068470
1 0.343586 0.090775
2 0.696852 0.923085
3 0.161288 0.376297
4 0.503365 0.701728
5 0.373529 0.621320
6 0.733098 0.866785
7 0.903162 0.663804
8 0.221881 0.978821
9 0.768057 0.120308
各种正常的引用方法:
df['a'] = 1
print(df)
df['a'].iloc[5:] = 2
print(df)
出现的结果也是预期的:
a b
0 1 0.068470
1 1 0.090775
2 1 0.923085
3 1 0.376297
4 1 0.701728
5 1 0.621320
6 1 0.866785
7 1 0.663804
8 1 0.978821
9 1 0.120308
a b
0 1 0.068470
1 1 0.090775
2 1 0.923085
3 1 0.376297
4 1 0.701728
5 2 0.621320
6 2 0.866785
7 2 0.663804
8 2 0.978821
9 2 0.120308
然而,当根据条件筛选时:
df.loc[df['a']==2]['b'] = 10
print(df)
貌似赋值没有起作用,运行出的结果依然是上述最后一个结果。
a b
0 1 0.068470
1 1 0.090775
2 1 0.923085
3 1 0.376297
4 1 0.701728
5 2 0.621320
6 2 0.866785
7 2 0.663804
8 2 0.978821
9 2 0.120308
应该怎么办呢?根据spyder窗口的输出警告提出。
我去对应的网址上找到了最终答案。原来这种引用方式在官网的手册上明确说明,是不允许的。正确的方法应该是:
df.loc[df['a']==2,'b'] = 10
print(df)
这样就得到了正确的结果,看似简单的小问题,蕴含的是对一个处理工具官方文档的理解程度。
a b
0 1 0.509076
1 1 0.180524
2 1 0.315487
3 1 0.380127
4 1 0.932072
5 2 10.000000
6 2 10.000000
7 2 10.000000
8 2 10.000000
9 2 10.000000
附警告信息里的网址:http://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy