python知识之pandas基础

1、pandas的安装

python环境下直接使用pip或者conda安装

pip install pandas
conda install pandas
2、pandas的介绍

pandas是基于numpy的一种工具,该工具是为了解决数据分析任务而创建的。pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

pandas基于两种数据类型:series与dataframe

3、Series对象

Series是pandas中最基本的对象,类似于一维数组。和数组不同的是,Series能为数据自定义索引,然后通过索引来访问数组中的数据

3.1 创建series对象
In [1]: import pandas as pd   
In [2]: pd.Series([1,2,3,4])    # 使用一维数组创建,使用默认索引,[0,1,2,3....]
Out[2]:
0    1
1    2
2    3
3    4
dtype: int64
 # 使用一维数组创建,自定义标签索引,["a","b","c","d"]
In [3]: pd.Series([1,2,3,4], index=list("abcd"))
Out[3]:
a    1
b    2
c    3
d    4
dtype: int64

In [4]: dic = {"name": "mike", "age": 10, "sex": "male"}
In [5]: sel = pd.Series(dic)			# 利用字典创建,键会自动变成标签索引
In [6]:	sel
Out[6]:
name    mike
age       10
sex     male
dtype: object

In [7]: sel.index.tolist()					# 获取标签索引
Out[7]: ['name', 'age', 'sex']

In [8]: sel.values.tolist()					 # 获取值
Out[8]: ['mike', 10, 'male']

In [11]: list(sel.iteritems())				# 获取标签索引键值对
Out[11]: [('name', 'mike'), ('age', 10), ('sex', 'male')]
3.2 series对象的索引和切片
In [12]: sel = pd.Series([1,2,3,4], index=list("abcd"))
In [13]: sel
Out[13]:
a    1
b    2
c    3
d    4
dtype: int64

In [14]: print("标签索引", sel['c'])		 # 利用标签索引取值
标签索引 3

In [15]: print("位置索引", sel[2])			# 利用位置索引取值
位置索引 3

In [16]: sel[["a","d"]]					 # 利用标签索引获取不连续的多个值
Out[16]:
a    1
d    4
dtype: int64

In [17]: sel[[0,3]]						 # 利用位置索引获取不连续的多个值
Out[17]:
a    1
d    4
dtype: int64

In [18]: sel["a":"d"]					# 利用标签索引切片获取连续的多个值,注意是左右都包含 
Out[18]:
a    1
b    2
c    3
d    4
dtype: int64

In [19]: sel[0:3]					 # 利用位置索引切片获取连续的多个值,注意是左包含右不包含
Out[19]:
a    1
b    2
c    3
dtype: int64


In [20]: sel.index = list("bcda")   # index,重新定义标签索引
In [21]: sel
Out[21]:
b    1
c    2
d    3
a    4
dtype: int64

# reindex,生成一个新的Series,原Series有的索引则取对应的值,没有的索引则用NaN填充。
In [22]: sel1 = sel.reindex(list("abcdefa"))
In [23]: sel1
Out[23]:
a    4.0
b    1.0
c    2.0
d    3.0
e    NaN
f    NaN
a    4.0
dtype: float64

In [24]: sel.drop(["a","c"])		# 删除指定索引的值,注意是标签索引,而不是位置索引,也不是元素值
Out[24]:
b    1
d    3
dtype: int64
3.3 series的算术运算操作
  • series的算术运算都是基于索引(index)进行的,支持加减乘除等运算。
  • pandas会根据索引对相应的数据进行计算,结果会以浮点数的形式存储,避免丢失精度。
  • pandas如果在两个series里找不到相同的索引,对应的位置则会返回一个空值 NaN。
In [25]: a = pd.Series([1,2,3,4], index=list("abcd"))
In [26]: b = pd.Series([2,4,6,8], index=list("bcde"))
In [27]: a+b				 # 对应索引的数值相加,没有相同索引的地方返回NaN
Out[27]:
a     NaN
b     4.0
c     7.0
d    10.0
e     NaN
dtype: float64

In [28]: a*b					 # 对应索引的数值相乘,没有相同索引的地方返回NaN
Out[28]:
a     NaN
b     4.0
c    12.0
d    24.0
e     NaN
dtype: float64

In [29]: a[a>2]					 # 和数组类似,输出大于2的元素
Out[29]:
c    3
d    4
dtype: int64

In [30]: a*2						# a对应的所有数值都乘以2
Out[30]:
a    2
b    4
c    6
d    8
dtype: int64
4、DataFrame对象
4.1 创建DataFrame对象
In [35]: import pandas as pd
In [36]: import numpy as np
# 使用二维数组创建, 三行四列的数组,行索引(index)需要3个,列索引(columns)需要4个
In [37]: pd.DataFrame([[1,2,3,4],[5,6,7,8],[2,4,6,8]], index=[1,2,3], columns=list("abcd"))
Out[37]:
   a  b  c  d
1  1  2  3  4
2  5  6  7  8
3  2  4  6  8

# 使用字典创建,行索引由index决定,列索引由字典的键决定
In [38]: dic = {"name": ["mike", "lucy", "peter"],
    ...:		"age": [10, 12, 14],
    ...: 		"sex": ["boy", "girl", "boy"]}
In [39]: pd.DataFrame(dic, index=[1,2,3])
Out[39]:
    name  age   sex
1   mike   10   boy
2   lucy   12  girl
3  peter   14   boy

In [40]: df = pd.DataFrame.from_dict(dic)   	 # 使用from_dict创建,行索引默认从0开始
In [41]: df
Out[41]:
    name  age   sex
0   mike   10   boy
1   lucy   12  girl
2  peter   14   boy

In [42]: df.to_dict()			# to_dict()方法将DataFrame对象转换为字典
Out[42]:
{'name': {0: 'mike', 1: 'lucy', 2: 'peter'},
 'age': {0: 10, 1: 12, 2: 14},
 'sex': {0: 'boy', 1: 'girl', 2: 'boy'}}
4.2 DataFrame的常用属性和方法
In [41]: df
Out[41]:
    name  age   sex
0   mike   10   boy
1   lucy   12  girl
2  peter   14   boy

In [43]: df.shape				# 获取形状---行数和列数
Out[43]: (3, 3)

In [44]: df.dtypes				# 获取数据的类型
Out[44]:
name    object
age      int64
sex     object
dtype: object

In [45]: df.ndim					 # 获取维度
Out[45]: 2

In [46]: df.values						# 获取值
Out[46]:
array([['mike', 10, 'boy'],
       ['lucy', 12, 'girl'],
       ['peter', 14, 'boy']], dtype=object)

In [47]: df.index.tolist()				# 获取行索引
Out[47]: [0, 1, 2]

In [48]: df.columns.tolist()			# 获取列索引
Out[48]: ['name', 'age', 'sex']

In [49]: df.info()						# 展示df的概览信息
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 3 entries, 0 to 2
Data columns (total 3 columns):
name    3 non-null object
age     3 non-null int64
sex     3 non-null object
dtypes: int64(1), object(2)
memory usage: 152.0+ bytes

In [50]: df.head(2)						# 显示头2行,默认显示5行
Out[50]:
   name  age   sex
0  mike   10   boy
1  lucy   12  girl

In [51]: df.tail(2)						# 显示后2行,默认显示5行
Out[51]:
    name  age   sex
1   lucy   12  girl
2  peter   14   boy

In [52]: df.sample(2)            # 随机抽取2行
Out[52]:
    name  age  sex
2  peter   14  boy
0   mike   10  boy

In [53]: df.sort_values(by="name", ascending=False)		# 按照指定列进行排序
Out[53]:
    name  age   sex
2  peter   14   boy
0   mike   10   boy
1   lucy   12  girl

In [54: df["sex"].value_counts()                   # 统计指定字段中每个值的总数
Out[54]:
boy     2
girl    1
Name: sex, dtype: int64

In [55]: df.describe()             # 展示df 数值类型字段的统计信息
Out[55]:
        age
count   3.0
mean   12.0
std     2.0
min    10.0
25%    11.0
50%    12.0
75%    13.0
max    14.0
4.3 DataFrame的索引和切片
  • df.loc[],根据标签索引取值
  • df.iloc[],根据位置索引取值
  • 建议使用loc和iloc方法进行取值,这样对索引类型会一目了然。
In [62]: dic = {"name": ["mike", "lucy", "peter"],
    ...: 		"age": [10, 12, 14],
    ...: 		"sex": ["boy", "girl", "boy"]}
In [63]: df = pd.DataFrame(dic,index=["1","2","3"])
In [64]: df
Out[64]:
    name  age   sex
1   mike   10   boy
2   lucy   12  girl
3  peter   14   boy

In [65]: df[1:3][["name","age"]]     # 取连续多行的某两列,注意[1:3]是行位置索引,不是行标签索引
Out[65]:
    name  age
2   lucy   12
3  peter   14

In [66]: df[1:3]                     # 取连续多行
Out[66]:
    name  age   sex
2   lucy   12  girl
3  peter   14   boy

In [67]: df[0:1]                     # 取单独一行
Out[67]:
   name  age  sex
1  mike   10  boy

In [68]: df[["name","age"]]          # 取多列,注意是两个方括号 [[]]
Out[68]:
    name  age
1   mike   10
2   lucy   12
3  peter   14

In [69]: df[["name"]]                # 取单独一列,返回的是DataFrame类型
Out[69]:
    name
1   mike
2   lucy
3  peter

In [70]: df["name"]                  # 取单独一列,返回的是Series类型
Out[70]:
1     mike
2     lucy
3    peter
Name: name, dtype: object

In [71]: df.loc[["1","3"],["name","age"]]       # [[行,行],[列,列]],取不连续的多行和多列
Out[71]:
    name  age
1   mike   10
3  peter   14

In [72]: df.loc["1":"3",["name","age"]]       # [行:行,[列,列]],取连续的多行和不连续的多列
Out[72]:
    name  age
1   mike   10
2   lucy   12
3  peter   14

In [73]: df.loc['1',["name","age"]]            # 取某一行,多列
Out[73]:
name    mike
age       10
Name: 1, dtype: object

In [74]: df.loc['1',:]                          # 取某一行,所有列
Out[74]:
name    mike
age       10
sex      boy
Name: 1, dtype: object

In [75]: df.loc['1','name']                     # 取某一行,某一列
Out[75]: 'mike'

In [76]: df.iloc[[0,2],[0,2]]       # [[行,行],[列,列]],取不连续的多行和多列
Out[76]:
    name  sex
1   mike  boy
3  peter  boy

In [77]: df.iloc[0:2,[0,2]]       # [行:行,[列,列]],取连续的多行和不连续的多列
Out[77]:
   name   sex
1  mike   boy
2  lucy  girl

In [78]: df.iloc[0,[0,2]]            # 取某一行,多列
Out[78]:
name    mike
sex      boy
Name: 1, dtype: object

In [79]: df.iloc[0,:]                    # 取某一行,所有列
Out[79]:
name    mike
age       10
sex      boy
Name: 1, dtype: object

In [80]: df.iloc[:,1]                    # 取某一列
Out[80]:
1    10
2    12
3    14
Name: age, dtype: int64

In [81]: df.iloc[0,2]                     # 取某一行,某一列
Out[81]: 'boy'

df.iloc[0,2] = "girl"         # 通过索引修改值
4.4 DataFrame修改行、列索引
In [82]: df = pd.DataFrame(np.arange(9).reshape(3,3),index=["a","b","c"],columns=["a","b","c"])
In [83]: df.index = ["aa", "bb", "cc"]		 # 重新定义行索引

In [84]: df.columns = ["aa", "bb", "cc"]      # 重新定义列索引

In [85]: df
Out[85]:
    aa  bb  cc
aa   0   1   2
bb   3   4   5
cc   6   7   8

In [86]: df = pd.DataFrame(np.arange(9).reshape(3,3),index=["a","b","c"],columns=["a","b","c"])
# 使用rename分别重定义行索引和列索引,支持单个修改
In [87]: df.rename(index={"a":"aa"},columns={"b":"bb"})
Out[87]:
    a  bb  c
aa  0   1  2
b   3   4  5
c   6   7  8

In [88]: df = df.set_index("a", drop=False)  # 指定某一列的值作为行索引,drop=False表示保留该列
In [89]: df
Out[89]:
   a  b  c
a
0  0  1  2
3  3  4  5
6  6  7  8

In [90]: df.index.name = None                  # 去除索引的名字 a
In [91]: df
Out[91]:
   a  b  c
0  0  1  2
3  3  4  5
6  6  7  8
4.5 DataFrame添加数据和删除数据
In [92]: df = pd.DataFrame(np.arange(9).reshape(3,3),index=["a","b","c"],columns=["a","b","c"])
In [93]: df['d'] = [1,2,3]		 # 类似字典添加元素,在DataFrame后面添加一列,元素个数需要与行数一致
In [94]: df
Out[94]:
   a  b  c  d
a  0  1  2  1
b  3  4  5  2
c  6  7  8  3

In [96]: df.insert(1,"e",[1,2,3])    # insert,在指定列位置添加一列
In [97]: df
Out[97]:
   a  e  b  c  d
a  0  1  1  2  1
b  3  2  4  5  2
c  6  3  7  8  3

In [100]: df = pd.DataFrame(np.arange(9).reshape(3,3),index=["a","b","c"],columns=["a","b","c"]
In [101]: new = pd.DataFrame({"a":2,"b":3,"c":4},index=[0])
# append,在原数据最后添加数据,需要重新赋值给原对象,ignore_index表示忽略自身的索引
In [102]: df = df.append(new, ignore_index=True)
In [103]: df
Out[103]:
   a  b  c
0  0  1  2
1  3  4  5
2  6  7  8
3  2  3  4

# [0],要删除数据的索引,axis=0表示删除行,inplace=False 表示不在当前df执行此操作
In [105]: df.drop([0],axis=0,inplace=False)  
Out[105]:
   a  b  c
1  3  4  5
2  6  7  8
3  2  3  4
In [106]: df
Out[106]:
   a  b  c
0  0  1  2
1  3  4  5
2  6  7  8
3  2  3  4

 # ["a"],要删除数据的索引,axis=1表示删除列,inplace=True 表示在当前df执行此操作
In [107]: df.drop(["a"],axis=1,inplace=True)   
In [108]: df
Out[108]:
   b  c
0  1  2
1  4  5
2  7  8
3  3  4
5、 数据处理
5.1 去除空值数据
# Series去除空值
In [109]: import pandas as pd
In [110]: from numpy import nan as NaN
In [111]: a = pd.Series([2,4,NaN,5,NaN])
In [112]: a
Out[112]:
0    2.0
1    4.0
2    NaN
3    5.0
4    NaN
dtype: float64

In [113]: a.dropna()                    # dropna(),去除空值,返回去除后的对象
Out[113]:
0    2.0
1    4.0
3    5.0
dtype: float64

In [114]: a = pd.Series([2,4,NaN,5,NaN])
In [115]: a.notnull()                # notnull(),判断是否为空值,不是空值则在相应位置输出 True
Out[115]:
0     True
1     True
2    False
3     True
4    False
dtype: bool

In [116]: a.isnull()    # isnull(),判断是否为空值,是空值则在相应位置输出 True
Out[116]:
0    False
1    False
2     True
3    False
4     True
dtype: bool

In [117]: a[a.notnull()]                # 过滤空值,效果同dropna()
Out[117]:
0    2.0
1    4.0
3    5.0
dtype: float64

# DataFrame去除空值
In [118]: n = [[1,2,3],[NaN,NaN,3],[NaN,NaN,NaN],[6,7,NaN]]
In [119]: df = pd.DataFrame(n)
In [120]: df
Out[120]:
     0    1    2
0  1.0  2.0  3.0
1  NaN  NaN  3.0
2  NaN  NaN  NaN
3  6.0  7.0  NaN
In [121]: df.dropna()			# 默认去除所有包含NaN的行
Out[121]:
     0    1    2
0  1.0  2.0  3.0

In [123]: df.dropna(how="all")		 # how="all",只有全部为NaN的行,才会去除;默认为how="any"
Out[123]:
     0    1    2
0  1.0  2.0  3.0
1  NaN  NaN  3.0
3  6.0  7.0  NaN

In [124]: df.dropna(how="all",axis=1)	# how="all",axis=1,全部为NaN的列才会去除,默认为axis=0
Out[124]:
     0    1    2
0  1.0  2.0  3.0
1  NaN  NaN  3.0
2  NaN  NaN  NaN
3  6.0  7.0  NaN

In [125]: df.dropna(how="any",axis=1)  # how="any",axis=1,去除所有包含NaN的列,默认为axis=0
Out[125]:
Empty DataFrame
Columns: []
Index: [0, 1, 2, 3]

In [126]: df.dropna(thresh=2)			 # thresh=2,至少有2个NaN的行才会去除
Out[126]:
     0    1    2
0  1.0  2.0  3.0
3  6.0  7.0  NaN
5.2 填充缺失数据
In [120]: df
Out[120]:
     0    1    2
0  1.0  2.0  3.0
1  NaN  NaN  3.0
2  NaN  NaN  NaN
3  6.0  7.0  NaN

In [128]: df.fillna(0, inplace=False)           # 用常数来填充NaN,inplace=True在当前df执行操作
Out[128]:
     0    1    2
0  1.0  2.0  3.0
1  0.0  0.0  3.0
2  0.0  0.0  0.0
3  6.0  7.0  0.0

In [129]: df.fillna({0:0,1:11,2:22})             # 通过字典给不同的列填充不同的常数
Out[129]:
     0     1     2
0  1.0   2.0   3.0
1  0.0  11.0   3.0
2  0.0  11.0  22.0
3  6.0   7.0  22.0

In [130]: df.fillna(df.mean())                   # 填充平均值
Out[130]:
     0    1    2
0  1.0  2.0  3.0
1  3.5  4.5  3.0
2  3.5  4.5  3.0
3  6.0  7.0  3.0

In [131]: df.iloc[:,1].fillna(0)                 # 只填充指定的列
Out[131]:
0    2.0
1    0.0
2    0.0
3    7.0
Name: 1, dtype: float64

# method='ffill',用前面的值来填充;limit=1,限制填充的行数
In [132]: df.fillna(method='ffill',limit=1)     
Out[132]:
     0    1    2
0  1.0  2.0  3.0
1  1.0  2.0  3.0
2  NaN  NaN  3.0
3  6.0  7.0  NaN

# method='bfill',用后面的值来填充,axis=1,修改填充方向
In [133]: df.fillna(method='bfill',axis=1)      
Out[133]:
     0    1    2
0  1.0  2.0  3.0
1  3.0  3.0  3.0
2  NaN  NaN  NaN
3  6.0  7.0  NaN
5.3 去除重复数据
In [134]: n = [[1,2,3],[1,2,3],[4,5,6],[4,7,8]]
In [135]: df = pd.DataFrame(n,columns=list("abc"))
In [136]: df
Out[136]:
   a  b  c
0  1  2  3
1  1  2  3
2  4  5  6
3  4  7  8

In [137]: df.duplicated()				# duplicated(),判断每一行是否重复,返回bool值
Out[137]:
0    False
1     True
2    False
3    False
dtype: bool

In [138]: df.drop_duplicates()			# drop_duplicates(),去除全部的重复行
Out[138]:
   a  b  c
0  1  2  3
2  4  5  6
3  4  7  8

In [139]: df.drop_duplicates(["a"])		# drop_duplicates(["a"]),去除指定列重复的行
Out[139]:
   a  b  c
0  1  2  3
2  4  5  6

In [140]: df.drop_duplicates("a",keep="last")		# keep="last",保留重复行中的最后一行
Out[140]:
   a  b  c
1  1  2  3
3  4  7  8
6、数据合并和连接

数据合并、连接有三种方式:join,merge,concat

具体区别详见:https://blog.csdn.net/weixin_42384784/article/details/105188799

7、时间序列

pd.date_range(start, end, periods, freq, closed) ,其中start, end, periods必须至少指定其中的两个参数值

  • start, end 开始结束时间
  • periods ,分成的时间个数
  • freq,默认为“D” ,时间序列频率,有 D、B、H、T、S、M等可选参数。
  • closed,默认为None, 包含开始结束时间,为left时包含结束时间,不包含结束时间,为right时包含结束时间,不包含开始时间。
In [141]: pd.date_range(start="20200329",end="20200405")   # 默认freq="D"
Out[141]:
DatetimeIndex(['2020-03-29', '2020-03-30', '2020-03-31', '2020-04-01',
               '2020-04-02', '2020-04-03', '2020-04-04', '2020-04-05'],
              dtype='datetime64[ns]', freq='D')

In [142]: pd.date_range(start="20200329",end="20200405",closed="left")  # 不包含2020-04-05
Out[142]:
DatetimeIndex(['2020-03-29', '2020-03-30', '2020-03-31', '2020-04-01',
               '2020-04-02', '2020-04-03', '2020-04-04'],
              dtype='datetime64[ns]', freq='D')

# 把这段时间等分成10份,此时 freq=None
In [143]: pd.date_range(start="20200329",end="20200405",periods=10)  
Out[143]:
DatetimeIndex(['2020-03-29 00:00:00', '2020-03-29 18:40:00',
               '2020-03-30 13:20:00', '2020-03-31 08:00:00',
               '2020-04-01 02:40:00', '2020-04-01 21:20:00',
               '2020-04-02 16:00:00', '2020-04-03 10:40:00',
               '2020-04-04 05:20:00', '2020-04-05 00:00:00'],
              dtype='datetime64[ns]', freq=None)

In [144]: pd.date_range(start="20200329", periods=10, freq="5D")  # 10个时间,频率为5天
Out[144]:
DatetimeIndex(['2020-03-29', '2020-04-03', '2020-04-08', '2020-04-13',
               '2020-04-18', '2020-04-23', '2020-04-28', '2020-05-03',
               '2020-05-08', '2020-05-13'],
              dtype='datetime64[ns]', freq='5D')

In [145]: pd.date_range(start="20200329", periods=10)
Out[145]:
DatetimeIndex(['2020-03-29', '2020-03-30', '2020-03-31', '2020-04-01',
               '2020-04-02', '2020-04-03', '2020-04-04', '2020-04-05',
               '2020-04-06', '2020-04-07'],
              dtype='datetime64[ns]', freq='D')

df.truncate(before, after),将df里面before指定日期之前的值全部过滤掉,after指定日期之后的值全部过滤掉。

df.truncate(before="2020-03-29")     # 过滤 2020-03-29 之前的数据,得到2020-03-29之后的数据
df.truncate(after="2020-03-29")      # 过滤 2020-03-29 之后的数据,得到2020-03-29之前的数据
8、分组聚合
In [146]: dic = {"name": ["mike", "lucy", "peter"],
     ...: 		"age": [10, 12, 12],
     ...: 		"sex": ["boy", "girl", "boy"]}

In [147]: df = pd.DataFrame(dic,index=["1","2","3"])
In [148]: df_group = df.groupby("sex")       # 根据 sex这一列进行分组
In [149]: df_group_age = df.groupby(["sex","age"])   # 根据多列进行分组

In [150]: df_group.groups       # 查看分组
Out[150]:
{'boy': Index(['1', '3'], dtype='object'),
 'girl': Index(['2'], dtype='object')}

In [151]: df_group.count()           # 查看分组后其它列的数量
Out[151]:
      name  age
sex
boy      2    2
girl     1    1

In [152]: for name, group in df_group:       # 查看分组具体情况
     ...: 	print(name)                    # 组的名字
     ...: 	print(group)                    # 组的具体内容
boy
    name  age  sex
1   mike   10  boy
3  peter   12  boy
girl
   name  age   sex
2  lucy   12  girl

In [153]: df_group.get_group("boy")     # 选择具体分组
Out[153]:
    name  age  sex
1   mike   10  boy
3  peter   12  boy

常用的聚合函数:
在这里插入图片描述

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值