400-616-5551

您所在位置: 首页> 学习课程> python培训 | Pandas数据结构之DataFrame常见操作

python培训 | Pandas数据结构之DataFrame常见操作

发布百知教育 来源:学习课程 2019-12-10

  • 提取、添加、删除列

  • 用方法链分配新列

  • 索引 / 选择

  • 数据对齐和运算

  • 转置

  • DataFrame 应用 NumPy 函数

  • 控制台显示

  • DataFrame 列属性访问和 IPython 代码补全

提取、添加、删除列

DataFrame 就像带索引的 Series 字典,提取、设置、删除列的操作与字典类似:

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

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

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

In [64]: df
Out[64]: 
   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

删除(del、pop)列的方式也与字典类似:

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

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

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

标量值以广播的方式填充列:

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

In [69]: df
Out[69]: 
   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 [70]: df['one_trunc'] = df['one'][:2]

In [71]: df
Out[71]: 
   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

可以插入原生多维数组,但长度必须与 DataFrame 索引长度一致。

默认在 DataFrame 尾部插入列。insert 函数可以指定插入列的位置:

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

In [73]: df
Out[73]: 
   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

用方法链分配新列

受 dplyr 的 mutate 启发,DataFrame 提供了 assign() 方法,可以利用现有的列创建新列。

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

In [75]: iris.head()
Out[75]: 
   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 [76]: (iris.assign(sepal_ratio=iris['SepalWidth'] / iris['SepalLength'])
   ....:      .head())
   ....: 
Out[76]: 
   SepalLength  SepalWidth  PetalLength  PetalWidth         Name  sepal_ratio
0          5.1         3.5          1.4         0.2  Iris-setosa     0.686275
1          4.9         3.0          1.4         0.2  Iris-setosa     0.612245
2          4.7         3.2          1.3         0.2  Iris-setosa     0.680851
3          4.6         3.1          1.5         0.2  Iris-setosa     0.673913
4          5.0         3.6          1.4         0.2  Iris-setosa     0.720000

上例中,插入了一个预计算的值。还可以传递带参数的函数,在 assign 的 DataFrame 上求值。

In [77]: iris.assign(sepal_ratio=lambda x: (x['SepalWidth'] / x['SepalLength'])).head()
Out[77]: 
   SepalLength  SepalWidth  PetalLength  PetalWidth         Name  sepal_ratio
0          5.1         3.5          1.4         0.2  Iris-setosa     0.686275
1          4.9         3.0          1.4         0.2  Iris-setosa     0.612245
2          4.7         3.2          1.3         0.2  Iris-setosa     0.680851
3          4.6         3.1          1.5         0.2  Iris-setosa     0.673913
4          5.0         3.6          1.4         0.2  Iris-setosa     0.720000

assign 返回的都是数据副本,原 DataFrame 不变。

未引用 DataFrame 时,传递可调用的,不是实际要插入的值。这种方式常见于在操作链中调用assign 的操作。例如,将 DataFrame 限制为花萼长度大于 5 的观察值,计算比例,再制图:

In [78]: (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'))
   ....: 
Out[78]: <matplotlib.axes._subplots.AxesSubplot at 0x7f66075a7978>

上例用 assign 把函数传递给 DataFrame, 并执行函数运算。这是要注意的是,该 DataFrame 是筛选了花萼长度大于 5 以后的数据。首先执行的是筛选操作,再计算比例。这个例子就是对没有事先筛选 DataFrame 进行的引用。

assign 函数签名就是 **kwargs。键是新字段的列名,值为是插入值(例如,Series 或 NumPy 数组),或把 DataFrame 当做调用参数的函数。返回结果是插入新值的 DataFrame 副本。

0.23.0 版新增。

从 3.6 版开始,Python 可以保存 **kwargs 顺序。这种操作允许依赖赋值**kwargs 后的表达式,可以引用同一个 assign() 函数里之前创建的列 。

In [79]: dfa = pd.DataFrame({"A": [123],
   ....:                     "B": [456]})
   ....: 

In [80]: dfa.assign(C=lambda x: x['A'] + x['B'],
   ....:            D=lambda x: x['A'] + x['C'])
   ....: 
Out[80]: 
   A  B  C   D
0  1  4  5   6
1  2  5  7   9
2  3  6  9  12

第二个表达式里,x['C'] 引用刚创建的列,与 dfa['A'] + dfa['B'] 等效。

要兼容所有 Python 版本,可以把 assign 操作分为两部分。

In [81]: dependent = pd.DataFrame({"A": [111]})

In [82]: (dependent.assign(A=lambda x: x['A'] + 1)
   ....:           .assign(B=lambda x: x['A'] + 2))
   ....: 
Out[82]: 
   A  B
0  2  4
1  2  4
2  2  4

依赖赋值改变了 Python 3.6 及之后版本与 Python 3.6 之前版本的代码操作方式。

要想编写支持 3.6 之前或之后版本的 Python 代码,传递 assign 表达式时,要注意以下两点:

  • 更新现有的列

  • 在同一个 assign 引用刚建立的更新列

示例如下,更新列 “A”,然后,在创建 “B” 列时引用该列。

>>> dependent = pd.DataFrame({"A": [111]})
>>> dependent.assign(A=lambda x: x["A"] + 1, B=lambda x: x["A"] + 2)
 

Python 3.5 或更早版本的表达式在创建 B 列时引用的是 A 列的“旧”值 [1, 1, 1]。输出是:

A B 0 2 3 1 2 3 2 2 3 ¨G30G A B 0 2 4 1 2 4 2 2 4

索引 / 选择

索引基础用法如下:

操作句法结果
选择列df[col]Series
用标签选择行df.loc[label]Series
用整数位置选择行df.iloc[loc]Series
行切片df[5:10]DataFrame
用布尔向量选择行df[bool_vec]DataFrame

选择行返回 Series,索引是 DataFrame 的列:

In [83]: df.loc['b']
Out[83]: 
one              2
bar              2
flag         False
foo            bar
one_trunc        2
Name: b, dtype: object

In [84]: df.iloc[2]
Out[84]: 
one             3
bar             3
flag         True
foo           bar
one_trunc     NaN
Name: c, dtype: object

高级索引、切片技巧,请参阅索引。重建索引介绍重建索引 / 遵循新标签集的基础知识。


python培训班:http://www.baizhiedu.com/python2019


上一篇:应届生去公司找个Java程序员的职位需要什么技能?

下一篇:python培训班 | 5个顶级异步Python框架

相关推荐