Pandas学习笔记

不羁岁月 提交于 2019-12-26 00:33:31

Pandas是一个Python包,提供快速、灵活和富有表现力的数据结构,使关联或标记数据的使用既简单又直观。

它旨在成为Python中进行实际,真实世界数据分析的基础高级构建块。此次外还有更广泛的目标,即称为任何语言中最强大,最灵活的开源数据分析/操作工具。

适合许多不同类型的数据

  • 具有异构类型列的表格数据,如SQL表或Excel表
  • 有序和无序的时间序列数据
  • 具有行和列标签的任意矩阵数据
  • 任何其他形式的观察/统计数据集。实际上不需要将数据标记为放置在pandas数据结构中

主要数据结构是Series(一维)和DataFrame(二维)处理金融,统计,社会科学和许多工程领域中的绝大多数典型用例。Pandas建立在NumPy之上,与许多其他第三方库完美集成。

数据结构

数据对齐是固有的

  • import numpy as np
  • import pandas as pd
  • import matplotlib.pyplot as plt

Series是一维标记的数组,能够保存任何数据类型。轴标签统称为索引,创建系列的基本方法是调用

  • s = pd.Series(data,index=index)

data可以有很多不同的东西,比如

  • 一个Python字典
  • 一个ndarray
  • 标量 

传递的索引是轴标签列表。因此根据数据的不同,可以分为几种情况

来自ndarray

如果data是ndarray,则索引的长度必须与数据的长度相同。如果没有传递索引,将创建一个具有值的索引

pd.Series(np.random.rand(5))

来自dict

可以从dicts实例化

pd.Series({'b':1}) 

来自标量值

如果data是标量值,则必须提供索引。将重复该值以匹配索引的长度

pd.Series(5.,index=['a','b']) 

index是行索引,columns是列索引

可以对Series进行计算和切片等操作

系列也可以有一个name属性

s = pd.Series(np.random.randn(5),name='something')

DataFrame是一个二维标记数据结构,具有可能不同类型的列。可以将其视为电子表格或SQL表,或Series对象的字段。通常是最常用的pandas对象。接受不同类型的输入

  • 1D ndarray,list,dicts或Series的Dict
  • 二维numpy.ndarray
  • 结构化或记录ndarray
  • 一个Series
  • 另一个DataFrame

除了数据,还可以传递索引(行标签)和列(列标签)参数。如果传递索引和/或列,则可以保证生成的DataFrame的索引和/或列。

来自dict或Series的dicts

得到的指数将是各种系列的指标。如果有任何嵌套的dicts,将首先转换为Series。

In [34]: d = {'one' : pd.Series([1., 2., 3.], index=['a', 'b', 'c']),
   ....:      'two' : pd.Series([1., 2., 3., 4.], index=['a', 'b', 'c', 'd'])}
   ....: 

In [35]: df = pd.DataFrame(d)

In [36]: df
Out[36]: 
   one  two
a  1.0  1.0
b  2.0  2.0
c  3.0  3.0
d  NaN  4.0

In [37]: pd.DataFrame(d, index=['d', 'b', 'a'])
Out[37]: 
   one  two
d  NaN  4.0
b  2.0  2.0
a  1.0  1.0

In [38]: pd.DataFrame(d, index=['d', 'b', 'a'], columns=['two', 'three'])
Out[38]: 
   two three
d  4.0   NaN
b  2.0   NaN
a  1.0   NaN

通过访问索引和列数据,可以分别访问行和列标签

In [39]: df.index
Out[39]: Index(['a', 'b', 'c', 'd'], dtype='object')

In [40]: df.columns
Out[40]: Index(['one', 'two'], dtype='object')

来自ndarrays 、lists的字典

ndarrays必须都是相同的长度。如果传递索引,则它必须明显与数组的长度相同。如果没有传递索引,结果将是range(n)

In [41]: d = {'one' : [1., 2., 3., 4.],
   ....:      'two' : [4., 3., 2., 1.]}
   ....: 

In [42]: pd.DataFrame(d)
Out[42]: 
   one  two
0  1.0  4.0
1  2.0  3.0
2  3.0  2.0
3  4.0  1.0

In [43]: pd.DataFrame(d, index=['a', 'b', 'c', 'd'])
Out[43]: 
   one  two
a  1.0  4.0
b  2.0  3.0
c  3.0  2.0
d  4.0  1.0

来自structrued或record array

处理方式与数组的字段相同

In [44]: data = np.zeros((2,), dtype=[('A', 'i4'),('B', 'f4'),('C', 'a10')])

In [45]: data[:] = [(1,2.,'Hello'), (2,3.,"World")]

In [46]: pd.DataFrame(data)
Out[46]: 
   A    B         C
0  1  2.0  b'Hello'
1  2  3.0  b'World'

In [47]: pd.DataFrame(data, index=['first', 'second'])
Out[47]: 
        A    B         C
first   1  2.0  b'Hello'
second  2  3.0  b'World'

In [48]: pd.DataFrame(data, columns=['C', 'A', 'B'])
Out[48]: 
          C  A    B
0  b'Hello'  1  2.0
1  b'World'  2  3.0

来自dicts列表

In [49]: data2 = [{'a': 1, 'b': 2}, {'a': 5, 'b': 10, 'c': 20}]

In [50]: pd.DataFrame(data2)
Out[50]: 
   a   b     c
0  1   2   NaN
1  5  10  20.0

In [51]: pd.DataFrame(data2, index=['first', 'second'])
Out[51]: 
        a   b     c
first   1   2   NaN
second  5  10  20.0

In [52]: pd.DataFrame(data2, columns=['a', 'b'])
Out[52]: 
   a   b
0  1   2
1  5  10

来自元组

In [53]: pd.DataFrame({('a', 'b'): {('A', 'B'): 1, ('A', 'C'): 2},
   ....:               ('a', 'a'): {('A', 'C'): 3, ('A', 'B'): 4},
   ....:               ('a', 'c'): {('A', 'B'): 5, ('A', 'C'): 6},
   ....:               ('b', 'a'): {('A', 'C'): 7, ('A', 'B'): 8},
   ....:               ('b', 'b'): {('A', 'D'): 9, ('A', 'B'): 10}})
   ....: 
Out[53]: 
       a              b      
       b    a    c    a     b
A B  1.0  4.0  5.0  8.0  10.0
  C  2.0  3.0  6.0  7.0   NaN
  D  NaN  NaN  NaN  NaN   9.0

构造函数

DataFrame.from_dict采用dicts的dict或类似数组序列的dict并返回DataFrame。DataFrame除了默认情况下的orient参数外,它的操作类似于构造函数columns,但可以将其设置index为使用dict键作为行标签

In [54]: pd.DataFrame.from_dict(dict([('A', [1, 2, 3]), ('B', [4, 5, 6])]))
Out[54]: 
   A  B
0  1  4
1  2  5
2  3  6

如果设置orient='index',则键将是行标签。还可以传递所需的列名称

In [55]: pd.DataFrame.from_dict(dict([('A', [1, 2, 3]), ('B', [4, 5, 6])]),
   ....:                        orient='index', columns=['one', 'two', 'three'])
   ....: 
Out[55]: 
   one  two  three
A    1    2      3
B    4    5      6

DataFrame.from_record获取元组列表或带有结构化dtype的ndarray。类似于普通DataFrame构造函数,但生产的DataFrame索引可能是结构化dtype的特定字段

In [57]: pd.DataFrame.from_records(data, index='C')
Out[57]: 
          A    B
C               
b'Hello'  1  2.0
b'World'  2  3.0

列选择、添加、删除

可以将DataFrame视为类似索引的Series对象的dict。获取,设置和删除的工作方式与dict操作相同

In [58]: df['one']
Out[58]: 
a    1.0
b    2.0
c    3.0
d    NaN
Name: one, dtype: float64

In [59]: df['three'] = df['one'] * df['two']

In [60]: df['flag'] = df['one'] > 2

In [61]: df
Out[61]: 
   one  two  three   flag
a  1.0  1.0    1.0  False
b  2.0  2.0    4.0  False
c  3.0  3.0    9.0   True
d  NaN  4.0    NaN  False

删除

In [62]: del df['two']

In [63]: three = df.pop('three')

In [64]: df
Out[64]: 
   one   flag
a  1.0  False
b  2.0  False
c  3.0   True
d  NaN  False

插入

In [65]: df['foo'] = 'bar'

In [66]: df
Out[66]: 
   one   flag  foo
a  1.0  False  bar
b  2.0  False  bar
c  3.0   True  bar
d  NaN  False  bar

如果插入与DataFrame不具有相同索引的Series时,将符合DataFrame的索引

In [67]: df['one_trunc'] = df['one'][:2]

In [68]: df
Out[68]: 
   one   flag  foo  one_trunc
a  1.0  False  bar        1.0
b  2.0  False  bar        2.0
c  3.0   True  bar        NaN
d  NaN  False  bar        NaN

可以插入原始的ndarrays,但他们的长度必须与DataFrame索引的长度相匹配

默认情况下,列会在末尾插入。该insert函数可以用于插入列的特定位置

In [69]: df.insert(1, 'bar', df['one'])

In [70]: df
Out[70]: 
   one  bar   flag  foo  one_trunc
a  1.0  1.0  False  bar        1.0
b  2.0  2.0  False  bar        2.0
c  3.0  3.0   True  bar        NaN
d  NaN  NaN  False  bar        NaN

在方法链中分配新列

DataFrame有一种assign()方法可以创建从现有列派生的新列

In [71]: iris = pd.read_csv('data/iris.data')

In [72]: iris.head()
Out[72]: 
   SepalLength  SepalWidth  PetalLength  PetalWidth         Name
0          5.1         3.5          1.4         0.2  Iris-setosa
1          4.9         3.0          1.4         0.2  Iris-setosa
2          4.7         3.2          1.3         0.2  Iris-setosa
3          4.6         3.1          1.5         0.2  Iris-setosa
4          5.0         3.6          1.4         0.2  Iris-setosa

In [73]: (iris.assign(sepal_ratio = iris['SepalWidth'] / iris['SepalLength'])
   ....:      .head())
   ....: 
Out[73]: 
   SepalLength  SepalWidth  PetalLength  PetalWidth         Name  sepal_ratio
0          5.1         3.5          1.4         0.2  Iris-setosa       0.6863
1          4.9         3.0          1.4         0.2  Iris-setosa       0.6122
2          4.7         3.2          1.3         0.2  Iris-setosa       0.6809
3          4.6         3.1          1.5         0.2  Iris-setosa       0.6739
4          5.0         3.6          1.4         0.2  Iris-setosa       0.7200

我们插入了一个预先计算的值,还可以传入一个参数的函数,以便在分配给DataFrame上进行求值

In [74]: iris.assign(sepal_ratio = lambda x: (x['SepalWidth'] /
   ....:                                      x['SepalLength'])).head()
   ....: 
Out[74]: 
   SepalLength  SepalWidth  PetalLength  PetalWidth         Name  sepal_ratio
0          5.1         3.5          1.4         0.2  Iris-setosa       0.6863
1          4.9         3.0          1.4         0.2  Iris-setosa       0.6122
2          4.7         3.2          1.3         0.2  Iris-setosa       0.6809
3          4.6         3.1          1.5         0.2  Iris-setosa       0.6739
4          5.0         3.6          1.4         0.2  Iris-setosa       0.7200

assign始终返回数据的副本,保持原始DataFrame不变

当没有引用DataFrame时,传递可调用的,而不是要插入的实际值。这assign在操作链中使用时很常见

In [75]: (iris.query('SepalLength > 5')
   ....:      .assign(SepalRatio = lambda x: x.SepalWidth / x.SepalLength,
   ....:              PetalRatio = lambda x: x.PetalWidth / x.PetalLength)
   ....:      .plot(kind='scatter', x='SepalRatio', y='PetalRatio'))

索引选择

选择列:df[col]:系列

按标签选择行:df.loc[label]:系列

按整数位置选择行:df.iloc[loc]:系列

切片行:df[5:10]:数据帧

按布尔向量选择行:df[bool_vec]:数据帧

数据对齐和算术

DataFrame对象之间的数据对其自动在列和索引(行标签)上对齐。同样生成的对象具有列和行标签的并集

In [82]: df = pd.DataFrame(np.random.randn(10, 4), columns=['A', 'B', 'C', 'D'])

In [83]: df2 = pd.DataFrame(np.random.randn(7, 3), columns=['A', 'B', 'C'])

In [84]: df + df2
Out[84]: 
        A       B       C   D
0  0.0457 -0.0141  1.3809 NaN
1 -0.9554 -1.5010  0.0372 NaN
2 -0.6627  1.5348 -0.8597 NaN
3 -2.4529  1.2373 -0.1337 NaN

DataFrame和Series之间执行操作时,默认行为是在DataFrame列上对齐Series索引,从而按行进行广播

df - df.iloc[0]

 在使用时间序列数据的特殊情况下,DataFrame索引还包含日期,广播将按列进行

index = pd.date_range('1/1/2000', periods=8)df = pd.DataFrame(np.random.randn(8, 3), index=index, columns=list('ABC'))df*5+21/dfdf ** 4df1 & df2df1 | df2df1 ^ df2-df1

转置

要进行转置,需要访问T属性,类似于ndarray

df[:5].T

DataFrame与NumPy函数的互操作性

可以在DataFrame上使用其他的Numpy函数

np.exp(df)

np.asarray(df)

df.T.dot(df)

DataFrame列属性访问

如果DataFrame列标签是有效的Python变量名称,则可以像属性一样访问

df.A

基本功能

要查看Series或DataFrame对象的小样本,请使用head()和tail()方法。显示的默认元素数为5,但您可以传递自定义数字。

long_series = pd.Series(np.random.randn(100))

long_series.head() //查看头

long_series.tail(3) //查看末尾

属性和原始ndarray(s)

df.columns = [x.lower() for x in df.columns] //列名小写

df.values 访问实际数据

加速操作

pandas支持使用numexpr库和bottleneck库加速某些类型的二进制数值和布尔运算

pd.set_option('compute.use_bottleneck', False)
pd.set_option('compute.use_numexpr', False)

匹配和广播

数据框所拥有的方法add(),sub(),mul(),div()和相关的功能radd(),rsub()用于执行二进制运算。

对于广播行为,系列输入是主要关注点。可以通过axis关键字匹配索引或列。

填充值数据的操作

算术函数可以选择输入fill_value,即当缺少某个位置时需要替换的值。

df.add(df2,fill_value=0)

布尔缩减

可以使用empty,any(),all,bool()提供一种方法来概括一个布尔结果

  • (df>0).all()
  • (df>0).any()
  • df.empty

比较对象是否相等

df+df != df*2 这个表达式是错误的 

(df+df).equals(df*2) 应该使用这个表达式

比较类似数组的对象

pandas数据结构与标量值进行比较时,可以用下面方式执行元素比较 

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

In [65]: pd.Index(['foo', 'bar', 'baz']) == 'foo'
Out[65]: array([ True, False, False], dtype=bool)

pandas还处理相同长度的不同数组对象之间的元素比较

In [66]: pd.Series(['foo', 'bar', 'baz']) == pd.Index(['foo', 'bar', 'qux'])
Out[66]: 
0     True
1     True
2    False
dtype: bool

In [67]: pd.Series(['foo', 'bar', 'baz']) == np.array(['foo', 'bar', 'qux'])
Out[67]: 
0     True
1     True
2    False
dtype: bool

尝试比较Index或Series不同长度的对象将引发ValueError

注意:这个和NumPy的广播不一样

组合重叠数据集

两个相似数据集的组合,其中一个比较好。我们希望组合两个DataFrame对象,其中一个DataFrame中的缺失值有条件地填充来自其他DataFrame的类似标记的值。实现操作的函数是combine_first(),如同位置两边都存在则使用第一个。

In [70]: df1 = pd.DataFrame({'A' : [1., np.nan, 3., 5., np.nan],
   ....:                     'B' : [np.nan, 2., 3., np.nan, 6.]})
   ....: 

In [71]: df2 = pd.DataFrame({'A' : [5., 2., 4., np.nan, 3., 7.],
   ....:                     'B' : [np.nan, np.nan, 3., 4., 6., 8.]})
   ....: 

In [72]: df1
Out[72]: 
     A    B
0  1.0  NaN
1  NaN  2.0
2  3.0  3.0
3  5.0  NaN
4  NaN  6.0

In [73]: df2
Out[73]: 
     A    B
0  5.0  NaN
1  2.0  NaN
2  4.0  3.0
3  NaN  4.0
4  3.0  6.0
5  7.0  8.0

In [74]: df1.combine_first(df2)
Out[74]: 
     A    B
0  1.0  NaN
1  2.0  2.0
2  3.0  3.0
3  5.0  4.0
4  3.0  6.0
5  7.0  8.0

通用DataFrame组合

另一个DataFrame和组合器函数,对齐输入DataFrame,然后传递Series的组合器函数对(名称相同的列)

In [75]: combiner = lambda x, y: np.where(pd.isna(x), y, x)
In [76]: df1.combine(df2, combiner)

描述性统计

 

 

 

 

 

 

 

 

 

 

 

 

 

http://pandas.pydata.org/pandas-docs/stable/basics.html

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!