赞
踩
本文授权转载自Python大咖谈
禁止二次转载
大家好,我是老表
阅读文本大概需要 16 分钟
建议从头开始学习,本系列前四篇Series
提供了一个可以简单、快捷返回 datetime
属性值的访问器。这个访问器返回的也是 Series,索引与现有的 Series 一样。
- # datetime
- In [264]: s = pd.Series(pd.date_range('20130101 09:10:12', periods=4))
-
- In [265]: s
- Out[265]:
- 0 2013-01-01 09:10:12
- 1 2013-01-02 09:10:12
- 2 2013-01-03 09:10:12
- 3 2013-01-04 09:10:12
- dtype: datetime64[ns]
-
- In [266]: s.dt.hour
- Out[266]:
- 0 9
- 1 9
- 2 9
- 3 9
- dtype: int64
-
- In [267]: s.dt.second
- Out[267]:
- 0 12
- 1 12
- 2 12
- 3 12
- dtype: int64
-
- In [268]: s.dt.day
- Out[268]:
- 0 1
- 1 2
- 2 3
- 3 4
- dtype: int64
用下列表达式进行筛选非常方便:
- In [269]: s[s.dt.day == 2]
- Out[269]:
- 1 2013-01-02 09:10:12
- dtype: datetime64[ns]
还可以轻易实现时区转换:
- In [270]: stz = s.dt.tz_localize('US/Eastern')
-
- In [271]: stz
- Out[271]:
- 0 2013-01-01 09:10:12-05:00
- 1 2013-01-02 09:10:12-05:00
- 2 2013-01-03 09:10:12-05:00
- 3 2013-01-04 09:10:12-05:00
- dtype: datetime64[ns, US/Eastern]
-
- In [272]: stz.dt.tz
- Out[272]: <DstTzInfo 'US/Eastern' LMT-1 day, 19:04:00 STD>
还可以把这些操作连在一起:
- In [273]: s.dt.tz_localize('UTC').dt.tz_convert('US/Eastern')
- Out[273]:
- 0 2013-01-01 04:10:12-05:00
- 1 2013-01-02 04:10:12-05:00
- 2 2013-01-03 04:10:12-05:00
- 3 2013-01-04 04:10:12-05:00
- dtype: datetime64[ns, US/Eastern]
还可以用 Series.dt.strftime()
把 datetime
的值当成字符串进行格式化,支持与标准的 strftime()
同样的格式。
- # DatetimeIndex
- In [274]: s = pd.Series(pd.date_range('20130101', periods=4))
-
- In [275]: s
- Out[275]:
- 0 2013-01-01
- 1 2013-01-02
- 2 2013-01-03
- 3 2013-01-04
- dtype: datetime64[ns]
-
- In [276]: s.dt.strftime('%Y/%m/%d')
- Out[276]:
- 0 2013/01/01
- 1 2013/01/02
- 2 2013/01/03
- 3 2013/01/04
- dtype: object
- # PeriodIndex
- In [277]: s = pd.Series(pd.period_range('20130101', periods=4))
-
- In [278]: s
- Out[278]:
- 0 2013-01-01
- 1 2013-01-02
- 2 2013-01-03
- 3 2013-01-04
- dtype: period[D]
-
- In [279]: s.dt.strftime('%Y/%m/%d')
- Out[279]:
- 0 2013/01/01
- 1 2013/01/02
- 2 2013/01/03
- 3 2013/01/04
- dtype: object
.dt
访问器还支持 period
与 timedelta
。
- # period
- In [280]: s = pd.Series(pd.period_range('20130101', periods=4, freq='D'))
-
- In [281]: s
- Out[281]:
- 0 2013-01-01
- 1 2013-01-02
- 2 2013-01-03
- 3 2013-01-04
- dtype: period[D]
-
- In [282]: s.dt.year
- Out[282]:
- 0 2013
- 1 2013
- 2 2013
- 3 2013
- dtype: int64
-
- In [283]: s.dt.day
- Out[283]:
- 0 1
- 1 2
- 2 3
- 3 4
- dtype: int64
- # timedelta
- In [284]: s = pd.Series(pd.timedelta_range('1 day 00:00:05', periods=4, freq='s'))
-
- In [285]: s
- Out[285]:
- 0 1 days 00:00:05
- 1 1 days 00:00:06
- 2 1 days 00:00:07
- 3 1 days 00:00:08
- dtype: timedelta64[ns]
-
- In [286]: s.dt.days
- Out[286]:
- 0 1
- 1 1
- 2 1
- 3 1
- dtype: int64
-
- In [287]: s.dt.seconds
- Out[287]:
- 0 5
- 1 6
- 2 7
- 3 8
- dtype: int64
-
- In [288]: s.dt.components
- Out[288]:
- days hours minutes seconds milliseconds microseconds nanoseconds
- 0 1 0 0 5 0 0 0
- 1 1 0 0 6 0 0 0
- 2 1 0 0 7 0 0 0
- 3 1 0 0 8 0 0 0
::: tip 注意
用这个访问器处理不是 datetime
类型的值时,Series.dt
会触发 TypeError
错误。
:::
Series 支持字符串处理方法,操作数组中每个元素十分方便。这些方法会自动排除缺失值与空值,这也许是其最重要的特性。这些方法通过 Series 的 str
属性访问,一般情况下,这些操作的名称与内置的字符串方法一致。示例如下:
- In [289]: s = pd.Series(['A', 'B', 'C', 'Aaba', 'Baca', np.nan, 'CABA', 'dog', 'cat'])
-
- In [290]: s.str.lower()
- Out[290]:
- 0 a
- 1 b
- 2 c
- 3 aaba
- 4 baca
- 5 NaN
- 6 caba
- 7 dog
- 8 cat
- dtype: object
这里还提供了强大的模式匹配方法,但工业注意,模式匹配方法默认使用正则表达式。
参阅矢量化字符串方法了解完整内容。
Pandas 支持三种排序方式,按索引标签排序,按列里的值排序,按两种方式混合排序。
Series.sort_index()
与 DataFrame.sort_index()
方法用于按索引层级对 pandas 对象排序。
- In [291]: df = pd.DataFrame({
- .....: 'one': pd.Series(np.random.randn(3), index=['a', 'b', 'c']),
- .....: 'two': pd.Series(np.random.randn(4), index=['a', 'b', 'c', 'd']),
- .....: 'three': pd.Series(np.random.randn(3), index=['b', 'c', 'd'])})
- .....:
-
- In [292]: unsorted_df = df.reindex(index=['a', 'd', 'c', 'b'],
- .....: columns=['three', 'two', 'one'])
- .....:
-
- In [293]: unsorted_df
- Out[293]:
- three two one
- a NaN -1.152244 0.562973
- d -0.252916 -0.109597 NaN
- c 1.273388 -0.167123 0.640382
- b -0.098217 0.009797 -1.299504
-
- # DataFrame
- In [294]: unsorted_df.sort_index()
- Out[294]:
- three two one
- a NaN -1.152244 0.562973
- b -0.098217 0.009797 -1.299504
- c 1.273388 -0.167123 0.640382
- d -0.252916 -0.109597 NaN
-
- In [295]: unsorted_df.sort_index(ascending=False)
- Out[295]:
- three two one
- d -0.252916 -0.109597 NaN
- c 1.273388 -0.167123 0.640382
- b -0.098217 0.009797 -1.299504
- a NaN -1.152244 0.562973
-
- In [296]: unsorted_df.sort_index(axis=1)
- Out[296]:
- one three two
- a 0.562973 NaN -1.152244
- d NaN -0.252916 -0.109597
- c 0.640382 1.273388 -0.167123
- b -1.299504 -0.098217 0.009797
-
- # Series
- In [297]: unsorted_df['three'].sort_index()
- Out[297]:
- a NaN
- b -0.098217
- c 1.273388
- d -0.252916
- Name: three, dtype: float64
Series.sort_values()
方法用于按值对 Series 排序。DataFrame.sort_values()
方法用于按行列的值对 DataFrame 排序。DataFrame.sort_values()
的可选参数 by
用于指定按哪列排序,该参数的值可以是一列或多列数据。
- In [298]: df1 = pd.DataFrame({'one': [2, 1, 1, 1],
- .....: 'two': [1, 3, 2, 4],
- .....: 'three': [5, 4, 3, 2]})
- .....:
-
- In [299]: df1.sort_values(by='two')
- Out[299]:
- one two three
- 0 2 1 5
- 2 1 2 3
- 1 1 3 4
- 3 1 4 2
参数 by
支持列名列表,示例如下:
- In [300]: df1[['one', 'two', 'three']].sort_values(by=['one', 'two'])
- Out[300]:
- one two three
- 2 1 2 3
- 1 1 3 4
- 3 1 4 2
- 0 2 1 5
这些方法支持用 na_position
参数处理空值。
- In [301]: s[2] = np.nan
-
- In [302]: s.sort_values()
- Out[302]:
- 0 A
- 3 Aaba
- 1 B
- 4 Baca
- 6 CABA
- 8 cat
- 7 dog
- 2 NaN
- 5 NaN
- dtype: object
-
- In [303]: s.sort_values(na_position='first')
- Out[303]:
- 2 NaN
- 5 NaN
- 0 A
- 3 Aaba
- 1 B
- 4 Baca
- 6 CABA
- 8 cat
- 7 dog
- dtype: object
0.23.0 版新增。
通过参数 by
传递给 DataFrame.sort_values()
的字符串可以引用列或索引层名。
- # 创建 MultiIndex
- In [304]: idx = pd.MultiIndex.from_tuples([('a', 1), ('a', 2), ('a', 2),
- .....: ('b', 2), ('b', 1), ('b', 1)])
- .....:
-
- In [305]: idx.names = ['first', 'second']
-
- # 创建 DataFrame
- In [306]: df_multi = pd.DataFrame({'A': np.arange(6, 0, -1)},
- .....: index=idx)
- .....:
-
- In [307]: df_multi
- Out[307]:
- A
- first second
- a 1 6
- 2 5
- 2 4
- b 2 3
- 1 2
- 1 1
按 second
(索引)与 A
(列)排序。
- In [308]: df_multi.sort_values(by=['second', 'A'])
- Out[308]:
- A
- first second
- b 1 1
- 1 2
- a 1 6
- b 2 3
- a 2 4
- 2 5
::: tip 注意
如果字符串、列名、索引层名重名,会触发警告提示,并以列名为准。后期版本中,这种情况将会触发模糊错误。
:::
Series 支持 searchsorted()
方法,这与numpy.ndarray.searchsorted()
的操作方式类似。
- In [309]: ser = pd.Series([1, 2, 3])
-
- In [310]: ser.searchsorted([0, 3])
- Out[310]: array([0, 2])
-
- In [311]: ser.searchsorted([0, 4])
- Out[311]: array([0, 3])
-
- In [312]: ser.searchsorted([1, 3], side='right')
- Out[312]: array([1, 3])
-
- In [313]: ser.searchsorted([1, 3], side='left')
- Out[313]: array([0, 2])
-
- In [314]: ser = pd.Series([3, 1, 2])
-
- In [315]: ser.searchsorted([0, 3], sorter=np.argsort(ser))
- Out[315]: array([0, 2])
Series 支持 nsmallest()
与 nlargest()
方法,本方法返回 N 个最大或最小的值。对于数据量大的 Series
来说,该方法比先为整个 Series 排序,再调用 head(n)
这种方式的速度要快得多。
- In [316]: s = pd.Series(np.random.permutation(10))
-
- In [317]: s
- Out[317]:
- 0 2
- 1 0
- 2 3
- 3 7
- 4 1
- 5 5
- 6 9
- 7 6
- 8 8
- 9 4
- dtype: int64
-
- In [318]: s.sort_values()
- Out[318]:
- 1 0
- 4 1
- 0 2
- 2 3
- 9 4
- 5 5
- 7 6
- 3 7
- 8 8
- 6 9
- dtype: int64
-
- In [319]: s.nsmallest(3)
- Out[319]:
- 1 0
- 4 1
- 0 2
- dtype: int64
-
- In [320]: s.nlargest(3)
- Out[320]:
- 6 9
- 8 8
- 3 7
- dtype: int64
DataFrame
也支持 nlargest
与 nsmallest
方法。
- In [321]: df = pd.DataFrame({'a': [-2, -1, 1, 10, 8, 11, -1],
- .....: 'b': list('abdceff'),
- .....: 'c': [1.0, 2.0, 4.0, 3.2, np.nan, 3.0, 4.0]})
- .....:
-
- In [322]: df.nlargest(3, 'a')
- Out[322]:
- a b c
- 5 11 f 3.0
- 3 10 c 3.2
- 4 8 e NaN
-
- In [323]: df.nlargest(5, ['a', 'c'])
- Out[323]:
- a b c
- 5 11 f 3.0
- 3 10 c 3.2
- 4 8 e NaN
- 2 1 d 4.0
- 6 -1 f 4.0
-
- In [324]: df.nsmallest(3, 'a')
- Out[324]:
- a b c
- 0 -2 a 1.0
- 1 -1 b 2.0
- 6 -1 f 4.0
-
- In [325]: df.nsmallest(5, ['a', 'c'])
- Out[325]:
- a b c
- 0 -2 a 1.0
- 1 -1 b 2.0
- 6 -1 f 4.0
- 2 1 d 4.0
- 4 8 e NaN
列为多重索引时,还可以显式排序,用 by
可以指定所有层级。
- In [326]: df1.columns = pd.MultiIndex.from_tuples([('a', 'one'),
- .....: ('a', 'two'),
- .....: ('b', 'three')])
- .....:
-
- In [327]: df1.sort_values(by=('a', 'two'))
- Out[327]:
- a b
- one two three
- 0 2 1 5
- 2 1 2 3
- 1 1 3 4
- 3 1 4 2
在 pandas 对象上执行 copy()
方法,将复制底层数据(但不包括轴索引,因为轴索引不可变),并返回一个新的对象。注意,复制对象这种操作一般来说不是必须的。比如说,以下几种方式可以就地(inplace) 改变 DataFrame:
插入、删除、修改列
为 index
或 columns
属性赋值
对于同质数据,用 values
属性或高级索引即可直接修改值
注意,用 pandas 方法修改数据不会带来任何副作用,几乎所有方法都返回新的对象,不会修改原始数据对象。如果原始数据有所改动,唯一的可能就是用户显式指定了要修改原始数据。
大家好,我是老表
觉得本文不错的话,转发、留言、点赞,是对我最大的支持。
每日留言
说说你读完本文感受?
或者一句激励自己的话?
(字数不少于15字)
留言赠书
《深入浅出Python机器学习》
点击视频查看书籍介绍
长按扫码查看书籍详情
想进学习交流群
加微信:jjxksa888
备注:简说Python
2小时快速掌握Python基础知识要点。
完整Python基础知识要点
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。