首发于微信公众号东哥夜谈。欢迎关注东哥夜谈,让我们一起聊聊个人成长、投资、编程、电影、运动等话题。
本帐号所有文章均为原创。文章可以随意转载,但请务必注明作者。如果觉得文章有用,欢迎转发朋友圈分享。
1. 缘起
pandas 讲究整体操作,想对里面的一些数据进行一些批量操作的时候,挨个用纯 Python 的方法,挨个遍历。这样简单是足够简单,但很不 pandasic。那有没有更为简单一些的办法呢?
2. 操作
Series 有个 map
方法,就是把函数映射到里面每个单元上,对单元进行操作。比如昨天我们说过的用astype
修改元素类型,用 map
也可以实现。
In [3]: df = pd.DataFrame(np.random.randn(4,3), columns=list('bde'), index=['Utah','Ohio','Texas','Oregon'])
In [4]: df
Out[4]:
b d e
Utah 0.241315 -0.586773 -1.365804
Ohio 0.973860 -0.600773 0.437951
Texas 1.003621 -1.142369 -1.374085
Oregon -0.290861 0.728503 -1.356081
In [34]: b = df.b
In [35]: b
Out[35]:
Utah 0.241315
Ohio 0.973860
Texas 1.003621
Oregon -0.290861
Name: b, dtype: float64
创建了一个 Series,其 dtype 类型为 float。想要把它变成 float,可以 map 之。
In [36]: bs = b.map(str)
In [37]: bs
Out[37]:
Utah 0.2413152528188941
Ohio 0.9738595889440395
Texas 1.0036207238625463
Oregon -0.2908605268647543
Name: b, dtype: object
想再换成 float,可以继续 map 之。
In [7]: bf
Out[7]:
Utah 0.483243
Ohio -0.778462
Texas 1.581152
Oregon -0.109222
Name: b, dtype: float64
多次转换,变的是形式,不变的内心
In [8]: bf == b
Out[8]:
Utah True
Ohio True
Texas True
Oregon True
Name: b, dtype: bool
这样换来换去意义不大,但 map 将函数映射到 Series 里面的元素这个功能,还是蛮好使的。比如做工程研究,节点位移精确到小数点后两位就足够足够了,怎么样一次性把所有结果都变成小数点后两位呢?
In [10]: bl = b.map(lambda x: '%.2f' % x)
In [11]: bl
Out[11]:
Utah 0.48
Ohio -0.78
Texas 1.58
Oregon -0.11
Name: b, dtype: object
Oh yeah,将数据 lambda
一下格式就可以了。不过这样结果就变成字符串了,虽然不影响显示,但可能影响后及分析,便可以进一步优化之。
In [12]: bl = b.map(lambda x: float('%.2f' % x))
In [13]: bl
Out[13]:
Utah 0.48
Ohio -0.78
Texas 1.58
Oregon -0.11
Name: b, dtype: float64
lambda
只能用于这种简单的情况,更复杂的操作可以干脆定义一个函数调用。话说我总觉得lambda
有点多余,已经有功能更强大的函数了,为什么还要用它呢?仅仅是因为长得漂亮么?
3. 总结
今天我们讨论了如何对 Series 里面的元素进行批量操作,感觉一下子高大上了起来,不在总是不停的 loop 来纯 Python 了,吼吼!
一下子感觉对 pandas 的理解提升了一个档次有木有!