Pandas入门篇 | Python学习笔记

222 阅读8分钟

Pandas入门篇 | Python学习笔记

“开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 1 天,点击查看活动详情

Pandas 是 Python 的核心数据分析支持库,提供了快速、灵活、明确的数据结构,旨在简单、直观地处理关系型、标记型数据。

官网

Pandas 适用于处理以下类型的数据:

  • 表格型数据:如Excel文件,CSV,SQL数据库,JSON等
  • 时间序列数据:如股票价格,气候数据,日志文件等
  • 非结构化数据:如图像,文本,音频等

Pandas的主要数据结构是Series(一维数据)和DataFrame(二维数据)

  • Series是一维数组,类似于列表或数组,但提供了更多功能。它可以包含任意类型的数据,并具有标签或索引。
  • DataFrame是一个二维数据结构,类似于数据库或电子表格,可以包含多列数据。每一列可以是不同的数据类型,并且每行可以有标签或索引。

生成对象

用值列表生成 Series 时,Pandas 默认自动生成整数索引

 s = pd.Series([1, 3, 5, np.nan, 6, 8])
 0    1.0
 1    3.0
 2    5.0
 3    NaN
 4    6.0
 5    8.0
 dtype: float64

用 Series 字典对象生成 DataFrame:

 df2 = pd.DataFrame({'A': 1.,
                      'B': pd.Timestamp('20130102'),
                      'C': pd.Series(1, index=list(range(4)), dtype='float32'),
                      'D': np.array([3] * 4, dtype='int32'),
                      'E': pd.Categorical(["test", "train", "test", "train"]),
                      'F': 'foo'})
  
   A          B    C  D      E    F
 0  1.0 2013-01-02  1.0  3   test  foo
 1  1.0 2013-01-02  1.0  3  train  foo
 2  1.0 2013-01-02  1.0  3   test  foo
 3  1.0 2013-01-02  1.0  3  train  foo

用含日期时间索引与标签的 NumPy 数组生成 DataFrame

 dates = pd.date_range('20130101', periods=6)
 ​
 DatetimeIndex(['2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04',
                '2013-01-05', '2013-01-06'],
               dtype='datetime64[ns]', freq='D')
               
 df = pd.DataFrame(np.random.randn(6, 4), index=dates, columns=list('ABCD'))
 ​
    A         B         C         D
 2013-01-01  0.469112 -0.282863 -1.509059 -1.135632
 2013-01-02  1.212112 -0.173215  0.119209 -1.044236
 2013-01-03 -0.861849 -2.104569 -0.494929  1.071804
 2013-01-04  0.721555 -0.706771 -1.039575  0.271860
 2013-01-05 -0.424972  0.567020  0.276232 -1.087401
 2013-01-06 -0.673690  0.113648 -1.478427  0.524988

基本操作

二进制操作

DataFrame 支持 add()、sub()、mul()、div() 及 radd()、rsub() 等方法执行二进制操作。广播机制重点关注输入的 Series。通过 axis 关键字,匹配 index 或 columns 即可调用这些函数。

Series 与 Index 还支持 divmod() 内置函数,该函数同时执行向下取整除与模运算,返回两个与左侧类型相同的元组。

 df.shape  # 返回轴的维度

比较操作

Series 与 DataFrame 还支持 eq(等于)、ne(不等于)、lt(小于)、gt(大于)、le(小于等于)、ge(大于等于) 等二进制比较操作的方法:

 df.gt(df2)
 ​
  one    two  three
 a  False  False  False
 b  False  False  False
 c  False  False  False
 d  False  False  False

布尔简化

empty、any()、all()、bool() 可以把数据汇总简化至单个布尔值。

比较 array 型对象

用标量值与 Pandas 数据结构对比数据元素非常简单,但如果是对比两个非标量的话就一定要等长的

 pd.Series(['foo', 'bar', 'baz']) == 'foo'
 ​
 0     True
 1    False
 2    False
 dtype: bool
 ​

合并重叠数据集

合并两个相似的数据集,两个数据集里的其中一个的数据比另一个多。比如,展示特定经济指标的两个数据序列,其中一个是“高质量”指标,另一个是“低质量”指标。如果df1有值,就返回df1的值,如果为nan就使用df2的值

 df1.combine_first(df2)

数据查看

DataFrame 的列有不同数据类型

 df2.dtypes
 ​
 A           float64
 B    datetime64[ns]
 C           float32
 D             int32
 E          category
 F            object
 dtype: object

查看 DataFrame 头部和尾部数据

 df.head() #查看头部的数据,默认5个
 df.tail(3)  #查看尾部的3个数据

显示索引与列名:

 df.index
 df.columns

输出底层数据的 NumPy 对象

 df.to_numpy() #如果df都为浮点数,转换速度就很快,如果多种类型,就消耗较多资源了
                          # 输出不包含行索引和列标签
 #快速查看数据的统计摘要:
 df.describe()
 ​
 #转置数据
 df.T
 ​
 #按轴排序
 df.sort_index(axis=1, ascending=False)
 ​
 #按值排序
 df.sort_values(by='B')

选择

获取数据

 #选择单列,产生 Series,与 df.A 等效
 df['A']
 ​
 用 [ ] 切片行,产生df:
 df[0:3]
 ​
 ​

按标签选择(理解为坐标系的x,y也是可以的)

 #用标签提取数据
 df.loc[:, ['A', 'B']]
 ​
 #用标签切片,包含行与列结束点
 df.loc['20130102':'20130104', ['A', 'B']]
 ​
                    A         B
 2013-01-02  1.212112 -0.173215
 2013-01-03 -0.861849 -2.104569
 2013-01-04  0.721555 -0.706771
 ​
 #提取标量值:
 df.loc[dates[0], 'A']
 df.at[dates[0], 'A']

按位置选择

 #用整数位置选择
 df.iloc[3]
 ​
 #类似 NumPy / Python,用整数列表按位置切片
 df.iloc[[1, 2, 4], [0, 2]]
 ​
 ​

布尔索引

 #用单列的值选择数据:
 df[df.A > 0]
 ​
 #选择 DataFrame 里满足条件的值:
  df[df > 0]
  
                     A         B         C         D
 2013-01-01  0.469112       NaN       NaN       NaN
 2013-01-02  1.212112       NaN  0.119209       NaN
 2013-01-03       NaN       NaN       NaN  1.071804
 2013-01-04  0.721555       NaN       NaN  0.271860
 2013-01-05       NaN  0.567020  0.276232       NaN
 2013-01-06       NaN  0.113648       NaN  0.524988
 ​
 ​
 #用 isin() 筛选
 df2[df2['E'].isin(['two', 'four'])]

赋值

 #用索引自动对齐新增列的数据
  s1 = pd.Series([1, 2, 3, 4, 5, 6], index=pd.date_range('20130102', periods=6))
 ​
 2013-01-02    1
 2013-01-03    2
 2013-01-04    3
 2013-01-05    4
 2013-01-06    5
 2013-01-07    6
 Freq: D, dtype: int64
 ​
 df['F'] = s1 #然后这个df就得到了上面的值
 ​
 #按标签赋值:
 df.at[dates[0], 'A'] = 0
 ​
 #按位置赋值
 df.iat[0, 1] = 0
 ​
 #按 NumPy 数组赋值:
 df.loc[:, 'D'] = np.array([5] * len(df))
 ​
 ​

缺失值

Pandas 主要用 np.nan 表示缺失数据。 计算时,默认不包含空值

 #删除所有含缺失值的行
 df1.dropna(how='any')
 
 #填充缺失值:
 df1.fillna(value=5)
 
 #提取 nan 值的布尔掩码:
 pd.isna(df1)
  A      B      C      D      F      E
 2013-01-01  False  False  False  False   True  False
 2013-01-02  False  False  False  False  False  False
 2013-01-03  False  False  False  False  False   True
 2013-01-04  False  False  False  False  False   True

运算

统计

一般情况下,运算时排除缺失值。

 #描述性统计
 df.mean()
 
  s = pd.Series([1, 3, 5, np.nan, 6, 8], index=dates).shift(2)  #shift值向下移动两个,原本没有的就为nan了
  
  2013-01-01    NaN
 2013-01-02    NaN
 2013-01-03    1.0
 2013-01-04    3.0
 2013-01-05    5.0
 2013-01-06    NaN
 Freq: D, dtype: float64
 
 df.sub(s, axis='index')
                    A         B         C    D    F
 2013-01-01       NaN       NaN       NaN  NaN  NaN
 2013-01-02       NaN       NaN       NaN  NaN  NaN
 2013-01-03 -1.861849 -3.104569 -1.494929  4.0  1.0
 2013-01-04 -2.278445 -3.706771 -4.039575  2.0  0.0
 2013-01-05 -5.424972 -4.432980 -4.723768  0.0 -1.0
 2013-01-06       NaN       NaN       NaN  NaN  NaN

下表为常用函数汇总表。每个函数都支持 level 参数,仅在数据对象为结构化 Index 时使用

函数描述
count统计非空值数量
sum汇总值
mean平均值
mad平均绝对偏差
median数中位数
min最小值
max最大值
mode众数
abs绝对值
prod乘积
std贝塞尔校正的样本标准偏差
var无偏方差
sem平均值的标准误差
skew样本偏度 (第三阶)
kurt样本峰度 (第四阶)
quantile样本分位数 (不同 % 的值)
cumsum累加
cumprod累乘
cummax累积最大值
cummin累积最小值

最大值与最小值对应的索引

Series 与 DataFrame 的 idxmax() 与 idxmin() 函数计算最大值与最小值对应的索引, 只返回匹配到的第一个值的 Index

Series 支持 nsmallest() 与 nlargest() 方法,本方法返回 N 个最大或最小的值。对于数据量大的 Series 来说,该方法比先为整个 Series 排序,再调用 head(n) 这种方式的速度要快得多。

s5.mode()可以返回众数

离散化与分位数

直方图

 s = pd.Series(np.random.randint(0, 7, size=10)) # 随机产生10个 0到7之间的数列
 ​
 0    3
 1    1
 2    1
 3    3
 4    0
 5    0
 6    1
 7    2
 8    5
 9    4
 dtype: int32
 ​
 s.value_counts() # 计算该值的数量
 1    3
 3    2
 0    2
 5    1
 4    1
 2    1
 dtype: int64
 ​

合并

结合 concat用于连接pandas对象

 pieces = [df[:3], df[3:7], df[7:]]
 pd.concat(pieces)

连接(join)

SQL 风格的合并

追加(Append)

这部分内容建议看这篇文章,总结得比较好!

分组

  • 分割:按条件把数据分割成多组;
  • 应用:为每组单独应用函数;
  • 组合:将处理结果组合成一个数据结构。

多列分组后,生成多层索引

 df.groupby(['A', 'B']).sum()  #.sum()可以汇总数据
 ​
                   C         D
 A   B                        
 bar one   -1.814470  2.395985
     three -0.595447  0.166599
     two   -0.392670 -0.136473
 foo one   -1.195665 -0.616981
     three  1.928123 -1.623033
     two    2.414034  1.600434

重塑

堆叠(Stack)

把 DataFrame 列压缩至一层,压缩后的 DataFrame 或 Series 具有多层索引, stack() 的逆操作是 unstack(),默认为拆叠最后一层。

数据透视表

 df = pd.DataFrame({'A': ['one', 'one', 'two', 'three'] * 3,
                                   'B': ['A', 'B', 'C'] * 4,
                                   'C': ['foo', 'foo', 'foo', 'bar', 'bar', 'bar'] * 2,
                                   'D': np.random.randn(12),
                                   'E': np.random.randn(12)})
                                   
   A  B    C         D         E
 0     one  A  foo  1.418757 -0.179666
 1     one  B  foo -1.879024  1.291836
 2     two  C  foo  0.536826 -0.009614
 3   three  A  bar  1.006160  0.392149
 4     one  B  bar -0.029716  0.264599
 5     one  C  bar -1.146178 -0.057409
 6     two  A  foo  0.100900 -1.425638
 7   three  B  foo -1.035018  1.024098
 8     one  C  foo  0.314665 -0.106062
 9     one  A  bar -0.773723  1.824375
 10    two  B  bar -1.170653  0.595974
 11  three  C  bar  0.648740  1.167115
 ​
 pd.pivot_table(df, values='D', index=['A', 'B'], columns=['C'])
 ​
 C             bar       foo
 A     B                    
 one   A -0.773723  1.418757
       B -0.029716 -1.879024
       C -1.146178  0.314665
 three A  1.006160       NaN
       B       NaN -1.035018
       C  0.648740       NaN
 two   A       NaN  0.100900
       B -1.170653       NaN
       C       NaN  0.536826

可视化

 ts = pd.Series(np.random.randn(1000),index=pd.date_range('1/1/2000', periods=1000))
 ts = ts.cumsum() #计算一个数组各行的累加值
 ts.plot()
 ​
 #折线图

用字典实现聚合

指定为哪些列应用哪些聚合函数时,需要把包含列名与标量(或标量列表)的字典传递给 DataFrame.agg。

注意:这里输出结果的顺序不是固定的,要想让输出顺序与输入顺序一致,请使用 OrderedDict。

astype

astype() 方法显式地把一种数据类型转换为另一种,默认操作为复制数据,就算数据类型没有改变也会复制数据,copy=False 改变默认操作模式。