Pandas-python数据处理和分析的库

Pandas是Python中用于数据处理和分析的库,尤其对于大数据行业的数据清洗很有帮助。

通过带有标签的列和索引,Pandas 使我们可以以一种所有人都能理解的方式来处理数据。它可以让我们毫不费力地从诸如 csv 类型的文件中导入数据。我们可以用它快速地对数据进行复杂的转换和过滤等操作。https://github.com/loveunk/machine-learning-deep-learning-notes/tree/master/python/pandas#references)

开始使用Pandas

对于使用 Python 库,第一步必然是import

1
import pandas as pd

数据类型 Data types

Pandas 基于两种数据类型,seriesdataframe

  • series 是一种一维的数据类型,其中的每个元素都有各自的标签。可以当作一个由带标签的元素组成的 numpy 数组。标签可以是数字或者字符。
  • dataframe 是一个二维的、表格型的数据结构。Pandasdataframe 可以储存许多不同类型的数据,并且每个轴都有标签。你可以把它当作一个 series 的字典。

文件操作

从文件导入数据

  • read_csv()读取csv文件为dataframe

    1
    2
    # Reading a csv into Pandas.
    df = pd.read_csv('uk_rain_2014.csv', header=0)
  • read_excel():用法类似read_csv(),用来读取Excel文件

  • df.head():查看前5行数据

  • df.tail():查看前最后5行数据

保存数据

  • to_csv():dataframe

    存入csv文件

    1
    2
    # Reading a csv into Pandas.
    df.to_csv('new.csv')

数据操作

列操作 Column operations

  • 获取一列,返回的是series
    • df['rain_octsep']
    • df.rain_octsep:也像访问属性一样访问列
  • 获取多列:df[['water_year', 'rain_octsep']]
  • Change Column labels 改变列标签
1
2
3
df.columns = ['water_year','rain_octsep', 'outflow_octsep',
'rain_decfeb', 'outflow_decfeb',
'rain_junaug', 'outflow_junaug']

行操作 Row operations

  • len(df):返回数据集的总行数

单元格操作 Cell operations

  • df.ix[i, j]:返回ij列的单元格数据,ij可以是index或者label
  • df.ix[i0:i1, j0:j1]:支持slicing,返回一个sub-dataframe
  • df['label'].unique():获得唯一的值列表

数据筛选

  • 根据column范围筛选数据(布尔过滤 boolean masking)
    • 注意:条件里不能用 and 关键字,因为会引发操作顺序的问题。必须用 & 和圆括号。
    • 当使用字符串过滤时,需要用.str.[string method],而不能直接在字符串上调用字符方法。
1
2
3
df1 = df[df['Released'] >= 1980]        # 年份大于1980的所有数据
df[(df.rain_octsep < 1000) & (df.outflow_octsep < 4000)]
df[df.water_year.str.startswith('199')] # 使用字符串过滤

索引 Index

可以根据索引来获取某一行,而且获取行数据的方法是根据标签的类型变化而变化的。

  • 如果标签是数字型的,可以通过 iloc 来引用:

    1
    df.iloc[30] # 获得index是30的行数据
  • 也许数据集中有年份或者年龄的列,可能想通过年份或年龄来引用行,这时候就可以设置一个(或者多个)新的索引:

    1
    2
    df = df.set_index(['water_year'])
    df.head(5)
  • 上面的代码仅将water_year

    列设置为索引。如果想设置多个索引,只需要在list

    中加入多个列的名字即可。

    1
    df.loc['2000/01']
  • 还有一个引用列的常用常用方法 ixloc 是基于标签的,而 iloc 是基于数字的,而 ix 是基于标签的查询方法,但它同时也支持数字型索引作为备选。注意ix 具有轻微的不可预测性,它所支持的数字型索引只是备选,可能会导致 ix 产生一些奇怪的结果,比如将一个数字解释为一个位置。而使用 ilocloc 会很安全、可预测。但 ixilocloc 要快一些。

排序 Sort

将索引排序通常会很有用,在 Pandas 中,我们可以对 dataframe 调用 sort_index 方法进行排序。

1
df.sort_index(ascending=False)

当将一列设置为索引的时候,它就不再是数据的一部分了。如果你想将索引恢复为数据,调用set_index 相反的方法 reset_index 即可:

对数据集应用函数

有时你想对数据集中的数据进行改变或者某种操作。比方说,你有一列年份的数据,你需要新的一列来表示这些年份对应的年代。Pandas 中有两个非常有用的函数, applyapplymap

1
2
3
4
5
6
7
def base_year(year):
base_year = year[:4]
base_year= pd.to_datetime(base_year).year
return base_year

df['year'] = df.water_year.apply(base_year)
df.head(5)

操作数据集的结构

  • groupby()
  • max() 、 min() 、mean()
  • unstack()
  • pivot():旋转

合并数据集

将有两个相关联的数据集放在一起:

1
2
3
4
rain_jpn = pd.read_csv('jpn_rain.csv')
rain_jpn.columns = ['year', 'jpn_rainfall']
uk_jpn_rain = df.merge(rain_jpn, on='year')
uk_jpn_rain.head(5)

需要通过 on 关键字来指定需要合并的列。通常你可以省略这个参数,Pandas 将会自动选择要合并的列。

快速画图

Matplotlib 很棒,但是想要绘制出还算不错的图表却要写不少代码,而有时你只是想粗略的做个图来探索下数据,搞清楚数据的含义。Pandas 通过 plot 来解决这个问题:

1
uk_jpn_rain.plot(x='year', y=['rain_octsep', 'jpn_rainfall'])

[img](https://camo.githubusercontent.com/fd10a2fb1ba629cbbe84dbfcea148ccf65d2e30f4717fae25b1b600e5f32cd12/68747470733a2f2f6c6975626a323031362e6769746875622e696f2f416b75616e2f696d616765732f74752e706e67)

案例

下面举了个例子,就是对数据进行提取,提取出该csv的国家的男性女性数量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import csv

import pandas as pd

# 数据集路径
path = 'survey.csv'

def run_main():
# 男性取值列表
male_set = {'male', 'm'}
# 女性取值列表
female_set = {'female', 'f'}
# 创建存储结果的空字典,键为国家,值为女性和男性数据的列表
result_dict = {}
# 加载数据
df = pd.read_csv(path)
for index, row in df.iterrows():
if(index%50):
print("正在处理:%d"%index)
Gender = row['Gender'].lower()
Country = row['Country']
if Country not in result_dict:
result_dict[Country] = [0,0]
if Gender in male_set:
result_dict[Country][0] += 1
elif Gender in female_set:
result_dict[Country][1] +=1

# 将提取数据写入文件
with open('country_gender.csv', 'w', newline='', encoding='utf-8') as csvfile:
csvwriter = csv.writer(csvfile, delimiter=',')
# 写入表头
csvwriter.writerow(['国家', '男性', '女性'])
# 写入统计结果,k为国家,v为性别数据
for k, v in list(result_dict.items()):
csvwriter.writerow([k, v[0], v[1]])

if __name__ == '__main__':
run_main()