python 数据处理 库_Python 数据处理库 pandas

核心数据结构

pandas最核心的就是Series和DataFrame两个数据结构。

名称维度说明

Series

1维

带有标签的同构类型数组

DataFrame

2维

表格结构,带有标签,大小可变,且可以包含异构的数据列

DataFrame可以看做是Series的容器,即:一个DataFrame中可以包含若干个Series。

series

由于Series是一堆结构的数据,我们可以直接通过数组来创建这种数据,像这样:

importpandas as pdimportnumpy as np

series1= pd.Series([1, 2, 3, 4])print("series1:\n{}\n".format(series1))#series1:#0 1#1 2#2 3#3 4#dtype: int64

输出的最后一行是Series中数据的类型,这里的数据都是int64类型的。

数据在第二列输出,第一列是数据的索引

我们分别打印出Series中的数据和索引

print("series1.values: {}\n".format(series1.values))print("series1.index: {}\n".format(series1.index))#series1.values: [1 2 3 4]#series1.index: RangeIndex(start=0, stop=4, step=1)

我们可以指定索引的类型,例如字符串

series2 = pd.Series([1, 2, 3, 4, 5, 6, 7],

index=["C", "D", "E", "F", "G", "A", "B"])print("series2:\n{}\n".format(series2))print("E is {}\n".format(series2["E"]))#series2:#C 1#D 2#E 3#F 4#G 5#A 6#B 7#dtype: int64

#E is 3

DataFrame

通过Numpy接口来创建一个4x4的矩阵,以此来创建DataFrame

1 importpandas as pd2 importnumpy as np3

4 df1 = pd.DataFrame(np.arange(16).reshape(4,4))5 print("df1:\n{}\n".format(df1))6

7 #df1:

8 #0 1 2 3

9 #0 0 1 2 3

10 #1 4 5 6 7

11 #2 8 9 10 11

12 #3 12 13 14 15

View Code

默认的索引和列名都是[0,N-1]的形式,同样我们可以指定列名和索引,

1 importpandas as pd2 importnumpy as np3

4 df2 = pd.DataFrame(np.arange(16).reshape(4,4),5 columns=["column1", "column2", "column3", "column4"],6 index=["a", "b", "c", "d"])7 print("df2:\n{}\n".format(df2))8

9 #df2:

10 #column1 column2 column3 column4

11 #a 0 1 2 3

12 #b 4 5 6 7

13 #c 8 9 10 11

14 #d 12 13 14 15

View Code

我们也可以指定结构来创建DataFrame

1 importpandas as pd2 importnumpy as np3

4 df3 = pd.DataFrame({"note" : ["C", "D", "E", "F", "G", "A", "B"],5 "weekday": ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]})6 print("df3:\n{}\n".format(df3))7

8 #df3:

9 #note weekday

10 #0 C Mon

11 #1 D Tue

12 #2 E Wed

13 #3 F Thu

14 #4 G Fri

15 #5 A Sat

16 #6 B Sun

View Code

注意:

DataFrame的不同列可以是不同的数据类型

如果以Series数组来创建DataFrame,每个Series将成为一行,而不是一列

1 importpandas as pd2 importnumpy as np3

4 noteSeries = pd.Series(["C", "D", "E", "F", "G", "A", "B"],5 index=[1, 2, 3, 4, 5, 6, 7])6 weekdaySeries = pd.Series(["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],7 index=[1, 2, 3, 4, 5, 6, 7])8 df4 =pd.DataFrame([noteSeries, weekdaySeries])9 print("df4:\n{}\n".format(df4))10

11 #df4:

12 #1 2 3 4 5 6 7

13 #0 C D E F G A B

14 #1 Mon Tue Wed Thu Fri Sat Sun

View Code

我们还可以“添加”或“删除”列数据

1 importpandas as pd2 importnumpy as np3

4 df3 = pd.DataFrame({"note" : ["C", "D", "E", "F", "G", "A", "B"],5 "weekday": ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]})6 df3["No."] = pd.Series([1, 2, 3, 4, 5, 6, 7])7 print("df3:\n{}\n".format(df3))8

9 del df3["weekday"]10 print("df3:\n{}\n".format(df3))11

12 #df3:

13 #note weekday No.

14 #0 C Mon 1

15 #1 D Tue 2

16 #2 E Wed 3

17 #3 F Thu 4

18 #4 G Fri 5

19 #5 A Sat 6

20 #6 B Sun 7

21

22 #df3:

23 #note No.

24 #0 C 1

25 #1 D 2

26 #2 E 3

27 #3 F 4

28 #4 G 5

29 #5 A 6

30 #6 B 7

View Code

index对象与数据访问

同样可以通过索引来获取DataFrame的行和列

1 print("df3.columns\n{}\n".format(df3.columns))2 print("df3.index\n{}\n".format(df3.index))3

4 #df3.columns

5 #Index(['note', 'No.'], dtype='object')

6

7 #df3.index

8 #RangeIndex(start=0, stop=7, step=1)

View Code

注意:

Index并非集合,因此其中可以包含重复的数据

Index对象的值是不可以改变,因此可以通过它安全的访问数据

DataFrane提供了下面两个操作符来访问其中的数据

loc:通过行和列的索引来访问数据

iloc:通过行和列的下标来访问数据

1 print("Note C, D is:\n{}\n".format(df3.loc[[0, 1], "note"]))2 print("Note C, D is:\n{}\n".format(df3.iloc[[0, 1], 0]))3

4 #Note C, D is:

5 #0 C

6 #1 D

7 #Name: note, dtype: object

8

9 #Note C, D is:

10 #0 C

11 #1 D

12 #Name: note, dtype: object

View Code

第一行代码访问了行索引为0和1,列索引为“note”的元素,第二行代码访问了行下标为0和1对于df3来说,行索引和行下标刚好是一样的,所以这里都是0和1,但它们却是不同的含义),列下标为0的元素。

文件操作

读取Excel文件

注:要读取Excel文件,还需要安装另外一个库;xlrd

pip install xlrd

1 importpandas as pd2 importnumpy as np3

4 df1 = pd.read_excel("data/test.xlsx")5 print("df1:\n{}\n".format(df1))6

7 #df1:

8 #C Mon

9 #0 D Tue

10 #1 E Wed

11 #2 F Thu

12 #3 G Fri

13 #4 A Sat

14 #5 B Sun

View Code

读取csv文件

1 C,Mon2 D,Tue3 E,Wed4 F,Thu5 G,Fri6 A,Sat

第一个CSV文件内容

1 C|Mon2 D|Tue3 E|Wed4 F|Thu5 G|Fri6 A|Sat

第二个CSV文件的内容

读取CSV文件

1 importpandas as pd2 importnumpy as np3 df2 = pd.read_csv("data/test1.csv")4 print("df2:\n{}\n".format(df2))5 #df3 = pd.read_csv("data/test2.csv", sep="|")

6 #print("df3:\n{}\n".format(df3))

View Code

我们可以发现,第二个CSV文件并不是通过逗号分隔的,我们通常指定分隔符的方式来读取这个文件。

read_csv支持非常多的参数用来调整读取的参数

参数说明

path

文件路径

sep或者delimiter

字段分隔符

header

列名的行数,默认是0(第一行)

index_col

列号或名称用作结果中的行索引

names

结果的列名称列表

skiprows

从起始位置跳过的行数

na_values

代替NA的值序列

comment

以行结尾分隔注释的字符

parse_dates

尝试将数据解析为datetime。默认为False

keep_date_col

如果将列连接到解析日期,保留连接的列。默认为False。

converters

列的转换器

dayfirst

当解析可以造成歧义的日期时,以内部形式存储。默认为False

data_parser

用来解析日期的函数

nrows

从文件开始读取的行数

iterator

返回一个TextParser对象,用于读取部分内容

chunksize

指定读取块的大小

skip_footer

文件末尾需要忽略的行数

verbose

输出各种解析输出的信息

encoding

文件编码

squeeze

如果解析的数据只包含一列,则返回一个Series

thousands

千数量的分隔符

详细的read_csv函数说明请参见这里:pandas.read_csv

处理无效值

主要有两种处理方法:直接忽略这些无效值;或者将无效值替换成有效值。

我们先创建一个包含无效值的数据结构。然后通过pandas.isna函数来确认哪些值是无效的:

1 importpandas as pd2 importnumpy as np3

4 df = pd.DataFrame([[1.0, np.nan, 3.0, 4.0],5 [5.0, np.nan, np.nan, 8.0],6 [9.0, np.nan, np.nan, 12.0],7 [13.0, np.nan, 15.0, 16.0]])8

9 print("df:\n{}\n".format(df));10 print("df:\n{}\n".format(pd.isna(df)))11

12 #df:

13 #0 1 2 3

14 #0 1.0 NaN 3.0 4.0

15 #1 5.0 NaN NaN 8.0

16 #2 9.0 NaN NaN 12.0

17 #3 13.0 NaN 15.0 16.0

18

19 #df:

20 #0 1 2 3

21 #0 False True False False

22 #1 False True True False

23 #2 False True True False

24 #3 False True False False

View Code

忽略无效值

我们可以通过pandas.DataFrame.dropna函数抛弃无效值

1 importpandas as pd2 importnumpy as np3

4 df = pd.DataFrame([[1.0, np.nan, 3.0, 4.0],5 [5.0, np.nan, np.nan, 8.0],6 [9.0, np.nan, np.nan, 12.0],7 [13.0, np.nan, 15.0, 16.0]])8

9 print("df.dropna():\n{}\n".format(df.dropna()));10

11 #df.dropna():

12 #Empty DataFrame

13 #Columns: [0, 1, 2, 3]

14 #Index: []

View Code

对于原先的结构,当无效值全部被抛弃之后,将不再是一个有效的DataFrame,所以才会是以上结果

我们也可以选择抛弃整列都是无效值的那一列:

1 importpandas as pd2 importnumpy as np3

4 df = pd.DataFrame([[1.0, np.nan, 3.0, 4.0],5 [5.0, np.nan, np.nan, 8.0],6 [9.0, np.nan, np.nan, 12.0],7 [13.0, np.nan, 15.0, 16.0]])8

9 print("df.dropna(axis=1,how='all'):\n{}\n".format(df.dropna(axis=1, how='all')));10

11 #df.dropna(axis=1, how='all'):

12 #0 2 3

13 #0 1.0 3.0 4.0

14 #1 5.0 NaN 8.0

15 #2 9.0 NaN 12.0

16 #3 13.0 15.0 16.0

View Code

注:axis=1表示列的轴。how可以取值’any’或者’all’,默认是前者。

替换无效值

我们也可以通过fillna函数将无效值替换成为有效值

1 importpandas as pd2 importnumpy as np3

4 df = pd.DataFrame([[1.0, np.nan, 3.0, 4.0],5 [5.0, np.nan, np.nan, 8.0],6 [9.0, np.nan, np.nan, 12.0],7 [13.0, np.nan, 15.0, 16.0]])8

9 print("df:\n{}\n".format(df));10

11 print("df.fillna(1):\n{}\n".format(df.fillna(1)));12

13 #df:

14 #0 1 2 3

15 #0 1.0 NaN 3.0 4.0

16 #1 5.0 NaN NaN 8.0

17 #2 9.0 NaN NaN 12.0

18 #3 13.0 NaN 15.0 16.0

19

20 #df.fillna(1):

21 #0 1 2 3

22 #0 1.0 1.0 3.0 4.0

23 #1 5.0 1.0 1.0 8.0

24 #2 9.0 1.0 1.0 12.0

25 #3 13.0 1.0 15.0 16.0

View Code

将无效值全部替换成同样的数据可能意义不大,因此我们可以指定不同的数据来进行填充。为了便于操作,在填充之前,我们可以先通过rename方法修改行和列的名称:

1 importpandas as pd2 importnumpy as np3

4 df = pd.DataFrame([[1.0, np.nan, 3.0, 4.0],5 [5.0, np.nan, np.nan, 8.0],6 [9.0, np.nan, np.nan, 12.0],7 [13.0, np.nan, 15.0, 16.0]])8

9 print("df:\n{}\n".format(df));10 print("df:\n{}\n".format(pd.isna(df)))11

12 df.rename(index={0: 'index1', 1: 'index2', 2: 'index3', 3: 'index4'},13 columns={0: 'col1', 1: 'col2', 2: 'col3', 3: 'col4'},14 inplace=True);15 df.fillna(value={'col2': 2}, inplace=True) #把第2列的空值变成2

16 df.fillna(value={'col3': 7}, inplace=True) #把第3列的空值变成7

17 print("df:\n{}\n".format(df));18

19 #df:

20 #0 1 2 3

21 #0 1.0 NaN 3.0 4.0

22 #1 5.0 NaN NaN 8.0

23 #2 9.0 NaN NaN 12.0

24 #3 13.0 NaN 15.0 16.0

25

26 #df:

27 #0 1 2 3

28 #0 False True False False

29 #1 False True True False

30 #2 False True True False

31 #3 False True False False

32

33 #df:

34 #col1 col2 col3 col4

35 #index1 1.0 2.0 3.0 4.0

36 #index2 5.0 2.0 7.0 8.0

37 #index3 9.0 2.0 7.0 12.0

38 #index4 13.0 2.0 15.0 16.0

View Code

处理字符串

Series的str字段包含了一系列的函数用来处理字符串。并且,这些函数会自动处理无效值。

1 importpandas as pd2

3 s1 = pd.Series(['1', '2', '3', '4', '5']);4 print("s1.str.rstrip():\n{}\n".format(s1.str.lstrip()))5 print("s1.str.strip():\n{}\n".format(s1.str.strip()))6 print("s1.str.isdigit():\n{}\n".format(s1.str.isdigit()))7

8 #s1.str.rstrip():

9 #0 1

10 #1 2

11 #2 3

12 #3 4

13 #4 5

14 #dtype: object

15

16 #s1.str.strip():

17 #0 1

18 #1 2

19 #2 3

20 #3 4

21 #4 5

22 #dtype: object

23

24 #s1.str.isdigit():

25 #0 False

26 #1 False

27 #2 False

28 #3 True

29 #4 True

30 #dtype: bool

View Code

我们还能对字符串进行大写、小写、以及字符串长度的处理。

1 importpandas as pd2

3 s2 = pd.Series(['Stairway to Heaven', 'Eruption', 'Freebird',4 'Comfortably Numb', 'All Along the Watchtower'])5 print("s2.str.lower():\n{}\n".format(s2.str.lower()))6 print("s2.str.upper():\n{}\n".format(s2.str.upper()))7 print("s2.str.len():\n{}\n".format(s2.str.len()))8

9 #s2.str.lower():

10 #0 stairway to heaven

11 #1 eruption

12 #2 freebird

13 #3 comfortably numb

14 #4 all along the watchtower

15 #dtype: object

16

17 #s2.str.upper():

18 #0 STAIRWAY TO HEAVEN

19 #1 ERUPTION

20 #2 FREEBIRD

21 #3 COMFORTABLY NUMB

22 #4 ALL ALONG THE WATCHTOWER

23 #dtype: object

24

25 #s2.str.len():

26 #0 18

27 #1 8

28 #2 8

29 #3 16

30 #4 24

31 #dtype: int64

View Code

参考文献

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值