当前位置:   article > 正文

Pandas入门教程

pandas

pandas是基于NumPy的一种数据分析工具,在机器学习任务中,我们首先需要对数据进行清洗和编辑等工作,pandas库大大简化了我们的工作量,熟练并掌握pandas常规用法是正确构建机器学习模型的第一步。

1. 安装

最常用的方法是通过Anaconda安装,在终端或命令符输入如下命令安装:

conda install pandas

若未安装Anaconda,使用Python自带的包管理工具pip来安装:

pip install pandas

2. 导入pandas库和查询相应的版本信息

  1. import numpy as np # pandas和numpy常常结合在一起使用,导入numpy库
  2. import pandas as pd # 导入pandas库
  3. print(pd.__version__) # 打印pandas版本信息
  4. #> 0.23.4
'
运行

3. pandas数据类型

pandas包含两种数据类型:series和dataframe,series是一种一维数据结构,每一个元素都带有一个索引,与一维数组的含义相似,其中索引可以为数字或字符串。

series结构名称:

|索引列|数据列
在这里插入图片描述
dataframe是一种二维数据结构,数据以表格形式(与excel类似)存储,有对应的行和列。

dataframe结构名称:
在这里插入图片描述

4. series教程

  • 从列表,数组,字典构建series
  1. mylist = list('abcedfghijklmnopqrstuvwxyz') # 列表
  2. myarr = np.arange(26) # 数组
  3. mydict = dict(zip(mylist, myarr)) # 字典
  4. # 构建方法
  5. ser1 = pd.Series(mylist)
  6. ser2 = pd.Series(myarr)
  7. ser3 = pd.Series(mydict)
  8. print(ser3.head()) # 打印前5个数据
  9. #> a 0
  10. b 1
  11. c 2
  12. d 4
  13. e 3
  14. dtype:int64
  • 使series的索引列转化为dataframe的列
  1. mylist = list('abcedfghijklmnopqrstuvwxyz')
  2. myarr = np.arange(26)
  3. mydict = dict(zip(mylist, myarr))
  4. ser = pd.Series(mydict)
  5. # series转换为dataframe
  6. df = ser.to_frame()
  7. # 索引列转换为dataframe的列
  8. df.reset_index(inplace=True)
  9. print(df.head())
  10. #> index 0
  11. 0 a 0
  12. 1 b 1
  13. 2 c 2
  14. 3 e 3
  15. 4 d 4
  • 结合多个series组成dataframe
  1. # 构建series1
  2. ser1 = pd.Series(list('abcedfghijklmnopqrstuvwxyz'))
  3. # 构建series2
  4. ser2 = pd.Series(np.arange(26))
  5. # 方法1,axis=1表示列拼接,0表示行拼接
  6. df = pd.concat([ser1, ser2], axis=1)
  7. # 与方法1相比,方法2设置了列名
  8. df = pd.DataFrame({'col1': ser1, 'col2': ser2})
  9. print(df.head())
  10. #> col1 col2
  11. 0 a 0
  12. 1 b 1
  13. 2 c 2
  14. 3 e 3
  15. 4 d 4
  • 命名列索引的名称
  1. ser = pd.Series(list('abcedfghijklmnopqrstuvwxyz'))
  2. # 命名索引列名称
  3. ser.name = 'alphabets'
  4. # 显示前5行数据
  5. ser.head()
  6. #> 0 a
  7. 1 b
  8. 2 c
  9. 3 e
  10. 4 d
  11. Name: alphabets, dtype: object
  • 如何获得series对象A中不包含series对象B的元素
  1. ser1 = pd.Series([1, 2, 3, 4, 5])
  2. ser2 = pd.Series([4, 5, 6, 7, 8])
  3. # 返回ser1不包含ser2的布尔型series
  4. ser3=~ser1.isin(ser2)
  5. # 获取ser不包含ser2的元素
  6. ser1[ser3]
  7. #> 0 1
  8. 1 2
  9. 2 3
  10. dtype: int64
  • 如何获得seriesA和seriesB不相同的项
  1. ser1 = pd.Series([1, 2, 3, 4, 5])
  2. ser2 = pd.Series([4, 5, 6, 7, 8])
  3. # 求ser1和ser2的并集
  4. ser_u = pd.Series(np.union1d(ser1, ser2))
  5. # 求ser1和ser2的交集
  6. ser_i = pd.Series(np.intersect1d(ser1, ser2))
  7. # ser_i在ser_u的补集就是ser1和ser2不相同的项
  8. ser_u[~ser_u.isin(ser_i)]
  9. #> 0 1
  10. 1 2
  11. 2 3
  12. 5 6
  13. 6 7
  14. 7 8
  15. dtype: int64
  • 获得数值series的四分位值
  1. # 设置随机数种子
  2. state = np.random.RandomState(100)
  3. # 从均值为5标准差为25的正态分布随机抽取5个点构成series
  4. ser = pd.Series(state.normal(10, 5, 25))
  5. # 求ser的四分位数
  6. np.percentile(ser, q=[0, 25, 50, 75, 100])
  7. #> array([ 1.25117263, 7.70986507, 10.92259345, 13.36360403, 18.0949083 ])
  • 获得series中单一项的频率计数
  1. #从0~7随机抽取30个列表值,组成series
  2. ser = pd.Series(np.take(list('abcdefgh'), np.random.randint(8, size=30)))
  3. # 对该series进行计数
  4. ser.value_counts()
  5. #> d 8
  6. g 6
  7. b 6
  8. a 5
  9. e 2
  10. h 2
  11. f 1
  12. dtype: int64
  • 保留series中前两个频次最多的项,其他项替换为‘other’
  1. np.random.RandomState(100)
  2. # 从1~4均匀采样12个点组成series
  3. ser = pd.Series(np.random.randint(1, 5, [12]))
  4. # 除前两行索引对应的值不变,后几行索引对应的值为Other
  5. ser[~ser.isin(ser.value_counts().index[:2])] = 'Other'
  6. ser
  7. #> 0 Other
  8. 1 4
  9. 2 2
  10. 3 2
  11. 4 4
  12. 5 Other
  13. 6 Other
  14. 7 Other
  15. 8 4
  16. 9 4
  17. 10 4
  18. 11 2
  19. dtype: object
  • 对数值series分成10个相同数目的组

换个角度理解,对数值series离散化成10个类别(categorical)值

  1. ser = pd.Series(np.random.random(20))
  2. # 离散化10个类别值,只显示前5行的数据
  3. pd.qcut(ser, q=[0, .10, .20, .3, .4, .5, .6, .7, .8, .9, 1],
  4. labels=['1st', '2nd', '3rd', '4th', '5th', '6th', '7th', '8th', '9th', '10th']).head()
  5. #>
  6. 0 3rd
  7. 1 1st
  8. 2 6th
  9. 3 6th
  10. 4 9th
  11. dtype: category
  12. Categories (10, object): [1st < 2nd < 3rd < 4th ... 7th < 8th < 9th < 10th]
  • 使numpy数组转化为给定形状的dataframe
  1. ser = pd.Series(np.random.randint(1, 10, 35))
  2. # serier类型转换numpy类型,然后重构
  3. df = pd.DataFrame(ser.values.reshape(7,5))
  4. print(df)
  5. #> 0 1 2 3 4 5
  6. 0 1 2 1 2 5
  7. 1 1 2 4 5 2
  8. 2 1 3 3 2 8
  9. 3 8 6 4 9 6
  10. 4 2 1 1 8 5
  11. 5 3 2 8 5 6
  12. 6 1 5 5 4 6
  • 找到series的值是3的倍数的位置
  1. ser = pd.Series(np.random.randint(1, 10, 7))
  2. print(ser)
  3. # 获取值是3倍数的索引
  4. np.argwhere(ser % 3==0)
  5. #> 0 6
  6. 1 8
  7. 2 6
  8. 3 7
  9. 4 6
  10. 5 2
  11. 6 4
  12. dtype: int64
  13. #> array([[0],
  14. [2],
  15. [4]])
  • 获取series中给定索引的元素(items)
  1. ser = pd.Series(list('abcdefghijklmnopqrstuvwxyz'))
  2. index = [0, 4, 8, 14, 20]
  3. # 获取指定索引的元素
  4. ser.take(index)
  5. #> 0 a
  6. 4 e
  7. 8 i
  8. 14 o
  9. 20 u
  10. dtype: object
  • 垂直和水平的拼接series
  1. ser1 = pd.Series(range(5))
  2. ser2 = pd.Series(list('abcde'))
  3. # 垂直拼接
  4. df = pd.concat([ser1, ser2], axis=0)
  5. # 水平拼接
  6. df = pd.concat([ser1, ser2], axis=1)
  7. print(df)
  8. #> 0 1 2
  9. 0 0 a
  10. 1 1 b
  11. 2 2 c
  12. 3 3 d
  13. 4 4 e
  • 获取series对象A中包含series对象B元素的位置
  1. # ser1必须包含ser2,否则会报错
  2. ser1 = pd.Series([10, 9, 6, 5, 3, 1, 12, 8, 13])
  3. ser2 = pd.Series([1, 3, 10, 13])
  4. # 方法 1
  5. [np.where(i == ser1)[0].tolist()[0] for i in ser2]
  6. # 方法 2
  7. [pd.Index(ser1).get_loc(i) for i in ser2]
  8. #> [5, 4, 0, 8]
  9. 16.如何计算series之间的均方差
  10. truth = pd.Series(range(10))
  11. pred = pd.Series(range(10)) + np.random.random(10)
  12. # 均方差
  13. np.mean((truth-pred)**2)
  14. #> 0.25508722434194103
  • 使series中每个元素的首字母为大写
  1. # series的元素为str类型
  2. ser = pd.Series(['how', 'to', 'kick', 'ass?'])
  3. # 方法 1
  4. ser.map(lambda x: x.title())
  5. # 方法 2 ,字符串相加
  6. ser.map(lambda x: x[0].upper() + x[1:])
  7. # 方法 3
  8. pd.Series([i.title() for i in ser])
  9. #> 0 How
  10. 1 To
  11. 2 Kick
  12. 3 Ass?
  13. dtype: object
  • 计算series中每个元素的字符串长度
  1. ser = pd.Series(['how', 'to', 'kick', 'ass?'])
  2. # 方法
  3. ser.map(lambda x: len(x))
  4. #> 0 3
  5. 1 2
  6. 2 4
  7. 3 4
  8. dtype: int64
  • 计算series的一阶导和二阶导
  1. ser = pd.Series([1, 3, 6, 10, 15, 21, 27, 35])
  2. # 求一阶导并转化为列表类型
  3. print(ser.diff().tolist())
  4. # 求二阶导并转化为列表类型
  5. print(ser.diff().diff().tolist())
  6. #> [nan, 2.0, 3.0, 4.0, 5.0, 6.0, 6.0, 8.0]
  7. [nan, nan, 1.0, 1.0, 1.0, 1.0, 0.0, 2.0]
  • 将一系列日期字符串转换为timeseries
  1. ser = pd.Series(['01 Jan 2010', '02-02-2011', '20120303', '2013/04/04', '2014-05-05', '2015-06-06T12:20'])
  2. pd.to_datetime(ser)
  3. #> 0 2010-01-01 00:00:00
  4. 1 2011-02-02 00:00:00
  5. 2 2012-03-03 00:00:00
  6. 3 2013-04-04 00:00:00
  7. 4 2014-05-05 00:00:00
  8. 5 2015-06-06 12:20:00
  9. dtype: datetime64[ns]
  • 从一个series中获取至少包含两个元音的元素
  1. ser = pd.Series(['Apple', 'Orange', 'Plan', 'Python', 'Money'])
  2. # 方法
  3. from collections import Counter
  4. # Counter是一个类字典类型,键是元素值,值是元素出现的次数,满足条件的元素返回True
  5. mask = ser.map(lambda x: sum([Counter(x.lower()).get(i, 0) for i in list('aeiou')]) >= 2)
  6. ser[mask]
  7. #> 0 Apple
  8. 1 Orange
  9. 4 Money
  10. dtype: object
  • 计算根据另一个series分组后的series均值
  1. fruit = pd.Series(np.random.choice(['apple', 'banana', 'carrot'], 10))
  2. weights = pd.Series(np.linspace(1, 10, 10))
  3. # 根据fruit对weight分组
  4. weightsGrouped = weights.groupby(fruit)
  5. print(weightsGrouped.indices)
  6. # 对分组后series求每个索引的平均值
  7. weightsGrouped.mean()
  8. #> {'apple': array([0, 3], dtype=int64), 'banana': array([1, 2, 4, 8],
  9. dtype=int64), 'carrot': array([5, 6, 7, 9], dtype=int64)}
  10. #> apple 2.50
  11. banana 4.75
  12. carrot 7.75
  13. dtype: float64
  • 计算两个series之间的欧氏距离
  1. p = pd.Series([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
  2. q = pd.Series([10, 9, 8, 7, 6, 5, 4, 3, 2, 1])
  3. \# 方法1
  4. sum((p - q)**2)**.5
  5. \# 方法2
  6. np.linalg.norm(p-q)
  7. #> 18.16590212458495
  • 在数值series中找局部最大值

局部最大值对应二阶导局部最小值

  1. ser = pd.Series([2, 10, 3, 4, 9, 10, 2, 7, 3])
  2. \# 二阶导
  3. dd = np.diff(np.sign(np.diff(ser)))
  4. \# 二阶导的最小值对应的值为最大值,返回最大值的索引
  5. peak_locs = np.where(dd == -2)[0] + 1
  6. peak_locs
  7. #> array([1, 5, 7], dtype=int64)
  • 如何用最少出现的字符替换空格符
  1. my_str = 'dbc deb abed gade'
  2. # 方法
  3. ser = pd.Series(list('dbc deb abed gade'))
  4. # 统计元素的频数
  5. freq = ser.value_counts()
  6. print(freq)
  7. # 求最小频数的字符
  8. least_freq = freq.dropna().index[-1]
  9. # 替换
  10. "".join(ser.replace(' ', least_freq))
  11. #> d 4
  12. 3
  13. b 3
  14. e 3
  15. a 2
  16. c 1
  17. g 1
  18. dtype: int64
  19. #> 'dbcgdebgabedggade'
  • 计算数值series的自相关系数
  1. ser = pd.Series(np.arange(20) + np.random.normal(1, 10, 20))
  2. # 求series的自相关系数,i为偏移量
  3. autocorrelations = [ser.autocorr(i).round(2) for i in range(11)]
  4. print(autocorrelations[1:])
  5. # 选择最大的偏移量
  6. print('Lag having highest correlation: ', np.argmax(np.abs(autocorrelations[1:]))+1)
  7. #> [0.33, 0.41, 0.48, 0.01, 0.21, 0.16, -0.11, 0.05, 0.34, -0.24]
  8. #> Lag having highest correlation: 3
  • 对series进行算术运算操作
  1. # 如何对series之间进行算法运算
  2. import pandas as pd
  3. series1 = pd.Series([3,4,4,4],['index1','index2','index3','index4'])
  4. series2 = pd.Series([2,2,2,2],['index1','index2','index33','index44'])
  5. # 加法
  6. series_add = series1 + series2
  7. print(series_add)
  8. # 减法
  9. series_minus = series1 - series2
  10. # series_minus
  11. # 乘法
  12. series_multi = series1 * series2
  13. # series_multi
  14. # 除法
  15. series_div = series1/series2
  16. series_div
  17. series是基于索引进行算数运算操作的,pandas会根据索引对数据进行运算,若series之间有不同的索引,对应的值就为Nan。结果如下:
  18. #加法:
  19. index1 5.0
  20. index2 6.0
  21. index3 NaN
  22. index33 NaN
  23. index4 NaN
  24. index44 NaN
  25. dtype: float64
  26. #除法:
  27. index1 1.5
  28. index2 2.0
  29. index3 NaN
  30. index33 NaN
  31. index4 NaN
  32. index44 NaN
  33. dtype: float64

5. dataframe教程

  • 从csv文件只读取前几行的数据
  1. # 只读取前2行和指定列的数据
  2. df = pd.read_csv('https://raw.githubusercontent.com/selva86/datasets/master/Cars93_miss.csv',nrows=2,usecols=['Model','Length'])
  3. df
  4. #> Model Length
  5. 0 Integra 177
  6. 1 Legend 195
  • 从csv文件中每隔n行来创建dataframe
  1. # 每隔50行读取一行数据
  2. df = pd.read_csv('https://raw.githubusercontent.com/selva86/datasets/master/BostonHousing.csv', chunksize=50)
  3. df2 = pd.DataFrame()
  4. for chunk in df:
  5. # 获取series
  6. df2 = df2.append(chunk.iloc[0,:])
  7. #显示前5行
  8. print(df2.head())
  9. #> crim zn indus chas nox rm age \
  10. 0 0.21977 0.0 6.91 0 0.44799999999999995 5.602 62.0
  11. 1 0.0686 0.0 2.89 0 0.445 7.416 62.5
  12. 2 2.7339700000000002 0.0 19.58 0 0.871 5.597 94.9
  13. 3 0.0315 95.0 1.47 0 0.40299999999999997 6.975 15.3
  14. 4 0.19072999999999998 22.0 5.86 0 0.431 6.718 17.5
  15. dis rad tax ptratio b lstat medv
  16. 0 6.0877 3 233 17.9 396.9 16.2 19.4
  17. 1 3.4952 2 276 18.0 396.9 6.19 33.2
  18. 2 1.5257 5 403 14.7 351.85 21.45 15.4
  19. 3 7.6534 3 402 17.0 396.9 4.56 34.9
  20. 4 7.8265 7 330 19.1 393.74 6.56 26.2
  • 改变导入csv文件的列值

改变列名‘medv’的值,当列值≤25时,赋值为‘Low’;列值>25时,赋值为‘High’。

  1. # 使用converters参数,改变medv列的值
  2. df = pd.read_csv('https://raw.githubusercontent.com/selva86/datasets/master/BostonHousing.csv',
  3. converters={'medv': lambda x: 'High' if float(x) > 25 else 'Low'})
  4. print(df.head())
  5. #> b lstat medv
  6. 0 396.90 4.98 Low
  7. 1 396.90 9.14 Low
  8. 2 392.83 4.03 High
  9. 3 394.63 2.94 High
  10. 4 396.90 5.33 High
  • 从csv文件导入指定的列
  1. # 导入指定的列:crim和medv
  2. df = pd.read_csv('https://raw.githubusercontent.com/selva86/datasets/master/BostonHousing.csv', usecols=['crim', 'medv'])
  3. # 打印前四行dataframe信息
  4. print(df.head())
  5. #> crim medv
  6. 0 0.00632 24.0
  7. 1 0.02731 21.6
  8. 2 0.02729 34.7
  9. 3 0.03237 33.4
  10. 4 0.06905 36.2
  • 得到dataframe的行,列,每一列的类型和相应的描述统计信息
  1. df = pd.read_csv('https://raw.githubusercontent.com/selva86/datasets/master/Cars93_miss.csv')
  2. # 打印dataframe的行和列
  3. print(df.shape)
  4. # 打印dataframe每列元素的类型显示前5行
  5. print(df.dtypes.head())
  6. # 统计各类型的数目,方法1
  7. print(df.get_dtype_counts())
  8. # 统计各类型的数目,方法2
  9. # print(df.dtypes.value_counts())
  10. # 描述每列的统计信息,如std,四分位数等
  11. df_stats = df.describe()
  12. # dataframe转化数组
  13. df_arr = df.values
  14. # 数组转化为列表
  15. df_list = df.values.tolist()
  16. #> (93, 27)
  17. Manufacturer object
  18. Model object
  19. Type object
  20. Min.Price float64
  21. Price float64
  22. dtype: object
  23. float64 18
  24. object 9
  25. dtype: int64
  • 获取给定条件的行和列
  1. import numpy as np
  2. df = pd.read_csv('https://raw.githubusercontent.com/selva86/datasets/master/Cars93_miss.csv')
  3. # print(df)
  4. # 获取最大值的行和列
  5. row, col = np.where(df.values == np.max(df.Price))
  6. # 行和列获取最大值
  7. print(df.iat[row[0], col[0]])
  8. df.iloc[row[0], col[0]]
  9. # 行索引和列名获取最大值
  10. df.at[row[0], 'Price']
  11. df.get_value(row[0], 'Price')
  12. #> 61.9
  • 重命名dataframe的特定列
  1. df1 = pd.DataFrame(data=np.array([[18,50],[19,51],[20,55]]),index=['man1','man2','man3'],columns=['age','weight'])
  2. print(df1)
  3. # 修改列名
  4. print("\nchange columns :\n")
  5. #方法1
  6. df1.rename(columns={'weight':'stress'})
  7. #方法2
  8. df1.columns.values[1] = 'stress'
  9. print(df1)
  10. #> age weight
  11. man1 18 50
  12. man2 19 51
  13. man3 20 55
  14. change columns :
  15. age stress
  16. man1 18 50
  17. man2 19 51
  18. man3 20 55
  • 如何检查dataframe中是否有缺失值
  1. df = pd.read_csv('https://raw.githubusercontent.com/selva86/datasets/master/Cars93_miss.csv')
  2. # 若有缺失值,则为Ture
  3. df.isnull().values.any()
  4. #> True
  5. 9. 如何统计dataframe的每列中缺失值的个数
  6. df = pd.read_csv('https://raw.githubusercontent.com/selva86/datasets/master/Cars93_miss.csv')
  7. # 获取每列的缺失值个数
  8. n_missings_each_col = df.apply(lambda x: x.isnull().sum())
  9. print(n_missings_each_col.head())
  10. #> Manufacturer 4
  11. Model 1
  12. Type 3
  13. Min.Price 7
  14. Price 2
  15. dtype: int64
  • 用平均值替换相应列的缺失值
  1. df = pd.read_csv('https://raw.githubusercontent.com/selva86/datasets/master/Cars93_miss.csv',nrows=10)
  2. print(df[['Min.Price','Max.Price']].head())
  3. # 平均值替换缺失值
  4. df_out = df[['Min.Price', 'Max.Price']] = df[['Min.Price', 'Max.Price']].apply(lambda x: x.fillna(x.mean()))
  5. print(df_out.head())
  6. #> Min.Price Max.Price
  7. 0 12.9 18.8
  8. 1 29.2 38.7
  9. 2 25.9 32.3
  10. 3 NaN 44.6
  11. 4 NaN NaN
  12. #> Min.Price Max.Price
  13. 0 12.9 18.8
  14. 1 29.2 38.7
  15. 2 25.9 32.3
  16. 3 23.0 44.6
  17. 4 23.0 29.9
  • 用全局变量作为apply函数的附加参数处理指定的列
  1. df = pd.read_csv('https://raw.githubusercontent.com/selva86/datasets/master/Cars93_miss.csv')
  2. print(df[['Min.Price', 'Max.Price']].head())
  3. # 全局变量
  4. d = {'Min.Price': np.nanmean, 'Max.Price': np.nanmedian}
  5. # 列名Min.Price的缺失值用平均值代替,Max.Price的缺失值用中值代替
  6. df[['Min.Price', 'Max.Price']] = df[['Min.Price', 'Max.Price']].apply(lambda x, d: x.fillna(d[x.name](x)), args=(d, ))
  7. print(df[['Min.Price', 'Max.Price']].head())
  8. #> Min.Price Max.Price
  9. 0 12.9 18.8
  10. 1 29.2 38.7
  11. 2 25.9 32.3
  12. 3 NaN 44.6
  13. 4 NaN NaN
  14. #> Min.Price Max.Price
  15. 0 12.900000 18.80
  16. 1 29.200000 38.70
  17. 2 25.900000 32.30
  18. 3 17.118605 44.60
  19. 4 17.118605 19.15
  • 以dataframe的形式选择特定的列
  1. df = pd.DataFrame(np.arange(20).reshape(-1, 5), columns=list('abcde'))
  2. # print(df)
  3. # 以dataframe的形式选择特定的列
  4. type(df[['a']])
  5. type(df.loc[:, ['a']])
  6. print(type(df.iloc[:, [0]]))
  7. # 以series的形式选择特定的列
  8. type(df.a)
  9. type(df['a'])
  10. type(df.loc[:, 'a'])
  11. print(type(df.iloc[:, 1]))
  12. #> <class 'pandas.core.frame.DataFrame'>
  13. <class 'pandas.core.series.Series'>
  • 改变dataframe中的列顺序
  1. df = pd.DataFrame(np.arange(20).reshape(-1, 5), columns=list('abcde'))
  2. print(df)
  3. # 交换col1和col2
  4. def switch_columns(df, col1=None, col2=None):
  5. colnames = df.columns.tolist()
  6. i1, i2 = colnames.index(col1), colnames.index(col2)
  7. colnames[i2], colnames[i1] = colnames[i1], colnames[i2]
  8. return df[colnames]
  9. df1 = switch_columns(df, 'a', 'c')
  10. print(df1)
  11. #> a b c d e
  12. 0 0 1 2 3 4
  13. 1 5 6 7 8 9
  14. 2 10 11 12 13 14
  15. 3 15 16 17 18 19
  16. #> c b a d e
  17. 0 2 1 0 3 4
  18. 1 7 6 5 8 9
  19. 2 12 11 10 13 14
  20. 3 17 16 15 18 19
  • 格式化dataframe的值
  1. df = pd.DataFrame(np.random.random(4)**10, columns=['random'])
  2. print(df)
  3. # 显示小数点后四位
  4. df.apply(lambda x: '%.4f' % x, axis=1)
  5. print(df)
  6. #> random
  7. 0 3.539348e-04
  8. 1 3.864140e-10
  9. 2 2.973575e-02
  10. 3 1.414061e-01
  11. #> random
  12. 0 3.539348e-04
  13. 1 3.864140e-10
  14. 2 2.973575e-02
  15. 3 1.414061e-01
  • 将dataframe中的所有值以百分数的格式表示
  1. df = pd.DataFrame(np.random.random(4), columns=['random'])
  2. # 格式化为小数点后两位的百分数
  3. out = df.style.format({
  4. 'random': '{0:.2%}'.format,
  5. })
  6. out
  7. #> random
  8. 0 48.54%
  9. 1 91.51%
  10. 2 90.83%
  11. 3 20.45%
  • 从dataframe中每隔n行构建dataframe
  1. df = pd.read_csv('https://raw.githubusercontent.com/selva86/datasets/master/Cars93_miss.csv')
  2. # 每隔20行读dataframe数据
  3. print(df.iloc[::20, :][['Manufacturer', 'Model', 'Type']])
  4. #> Manufacturer Model Type
  5. 0 Acura Integra Small
  6. 20 Chrysler LeBaron Compact
  7. 40 Honda Prelude Sporty
  8. 60 Mercury Cougar Midsize
  9. 80 Subaru Loyale Small
  • 得到列中前n个最大值对应的索引
  1. df = pd.DataFrame(np.random.randint(1, 15, 15).reshape(5,-1), columns=list('abc'))
  2. print(df)
  3. # 取'a'列前3个最大值对应的行
  4. n = 5
  5. df['a'].argsort()[::-1].iloc[:3]
  6. #> a b c
  7. 0 5 5 2
  8. 1 12 7 1
  9. 2 5 2 12
  10. 3 5 14 12
  11. 4 1 13 13
  12. #> 4 1
  13. 3 3
  14. 2 2
  15. Name: a, dtype: int64
  • 获得dataframe行的和大于100的最末n行索引
  1. df = pd.DataFrame(np.random.randint(10, 40, 16).reshape(-1, 4))
  2. print(df)
  3. # dataframe每行的和
  4. rowsums = df.apply(np.sum, axis=1)
  5. # 选取大于100的最末两行索引
  6. # last_two_rows = df.iloc[np.where(rowsums > 100)[0][-2:], :]
  7. nline = np.where(rowsums > 100)[0][-2:]
  8. nline
  9. #> 0 1 2 3
  10. 0 19 34 15 12
  11. 1 38 35 14 26
  12. 2 39 32 18 20
  13. 3 28 27 36 38
  14. #> array([2, 3], dtype=int64)
  • 从series中查找异常值并赋值
  1. ser = pd.Series(np.logspace(-2, 2, 30))
  2. # 小于low_per分位的数赋值为low,大于low_per分位的数赋值为high
  3. def cap_outliers(ser, low_perc, high_perc):
  4. low, high = ser.quantile([low_perc, high_perc])
  5. print(low_perc, '%ile: ', low, '|', high_perc, '%ile: ', high)
  6. ser[ser < low] = low
  7. ser[ser > high] = high
  8. return(ser)
  9. capped_ser = cap_outliers(ser, .05, .95)
  10. #> 0.05 %ile: 0.016049294076965887 | 0.95 %ile: 63.876672220183934
  • 交换dataframe的两行
  1. df = pd.DataFrame(np.arange(9).reshape(3, -1))
  2. print(df)
  3. # 函数
  4. def swap_rows(df, i1, i2):
  5. a, b = df.iloc[i1, :].copy(), df.iloc[i2, :].copy()
  6. # 通过iloc换行
  7. df.iloc[i1, :], df.iloc[i2, :] = b, a
  8. return df
  9. # 2和3行互换
  10. print(swap_rows(df, 1, 2))
  11. #> 0 1 2
  12. 0 0 1 2
  13. 1 3 4 5
  14. 2 6 7 8
  15. #> 0 1 2
  16. 0 0 1 2
  17. 1 6 7 8
  18. 2 3 4 5
  • 倒转dataframe的行
  1. df = pd.DataFrame(np.arange(9).reshape(3, -1))
  2. print(df)
  3. # 方法 1
  4. df.iloc[::-1, :]
  5. # 方法 2
  6. print(df.loc[df.index[::-1], :])
  7. #> 0 1 2
  8. 0 0 1 2
  9. 1 3 4 5
  10. 2 6 7 8
  11. #> 0 1 2
  12. 2 6 7 8
  13. 1 3 4 5
  14. 0 0 1 2
  • 对分类变量进行one-hot编码
  1. df = pd.DataFrame(np.arange(25).reshape(5,-1), columns=list('abcde'))
  2. print(df)
  3. # 对列'a'进行onehot编码
  4. df_onehot = pd.concat([pd.get_dummies(df['a']), df[list('bcde')]], axis=1)
  5. print(df_onehot)
  6. #> a b c d e
  7. 0 0 1 2 3 4
  8. 1 5 6 7 8 9
  9. 2 10 11 12 13 14
  10. 3 15 16 17 18 19
  11. 4 20 21 22 23 24
  12. #> 0 5 10 15 20 b c d e
  13. 0 1 0 0 0 0 1 2 3 4
  14. 1 0 1 0 0 0 6 7 8 9
  15. 2 0 0 1 0 0 11 12 13 14
  16. 3 0 0 0 1 0 16 17 18 19
  17. 4 0 0 0 0 1 21 22 23 24
  • 获取dataframe行方向上最大值个数最多的列
  1. df = pd.DataFrame(np.random.randint(1,100, 9).reshape(3, -1))
  2. print(df)
  3. # 获取每列包含行方向上最大值的个数
  4. count_series = df.apply(np.argmax, axis=1).value_counts()
  5. print(count_series)
  6. # 输出行方向最大值个数最多的列的索引
  7. print('Column with highest row maxes: ', count_series.index[0])
  8. #> 0 1 2
  9. 0 46 31 34
  10. 1 38 13 6
  11. 2 1 18 15
  12. #>统计列的最大值的个数
  13. 0 2
  14. 1 1
  15. dtype: int64
  16. #> Column with highest row maxes: 0
  • 得到列之间最大的相关系数
  1. df = pd.DataFrame(np.random.randint(1,100, 16).reshape(4, -1), columns=list('pqrs'), index=list('abcd'))
  2. # df
  3. print(df)
  4. # 得到四个列的相关系数
  5. abs_corrmat = np.abs(df.corr())
  6. print(abs_corrmat)
  7. # 得到每个列名与其他列的最大相关系数
  8. max_corr = abs_corrmat.apply(lambda x: sorted(x)[-2])
  9. # 显示每列与其他列的相关系数
  10. print('Maximum Correlation possible for each column: ', np.round(max_corr.tolist(), 2))
  11. #> p q r s
  12. a 59 99 1 34
  13. b 89 60 97 40
  14. c 43 35 14 6
  15. d 70 59 30 53
  16. #> p q r s
  17. p 1.000000 0.200375 0.860051 0.744529
  18. q 0.200375 1.000000 0.236619 0.438541
  19. r 0.860051 0.236619 1.000000 0.341399
  20. s 0.744529 0.438541 0.341399 1.000000
  21. #> Maximum Correlation possible for each column: [0.86 0.44 0.86 0.74]
  • 创建包含每行最小值与最大值比例的列
  1. df = pd.DataFrame(np.random.randint(1,100, 9).reshape(3, -1))
  2. print(df)
  3. # 方法1:axis=1表示行方向,
  4. min_by_max = df.apply(lambda x: np.min(x)/np.max(x), axis=1)
  5. # 方法2
  6. min_by_max = np.min(df, axis=1)/np.max(df, axis=1)
  7. min_by_max
  8. #> 0 1 2
  9. 0 81 68 59
  10. 1 45 73 23
  11. 2 20 22 69
  12. #> 0 0.728395
  13. 1 0.315068
  14. 2 0.289855
  15. dtype: float64
  • 创建包含每行第二大值的列
  1. df = pd.DataFrame(np.random.randint(1,100, 9).reshape(3, -1))
  2. print(df)
  3. # 行方向上取第二大的值组成series
  4. out = df.apply(lambda x: x.sort_values().unique()[-2], axis=1)
  5. # 构建dataframe新的列
  6. df['penultimate'] = out
  7. print(df)
  8. #> 0 1 2
  9. 0 28 77 1
  10. 1 43 19 69
  11. 2 29 30 72
  12. #> 0 1 2 penultimate
  13. 0 28 77 1 28
  14. 1 43 19 69 43
  15. 2 29 30 72 30
  • 归一化dataframe的所有列
  1. df = pd.DataFrame(np.random.randint(1,100, 80).reshape(8, -1))
  2. # 正态分布归一化
  3. out1 = df.apply(lambda x: ((x - x.mean())/x.std()).round(2))
  4. print('Solution Q1\n',out1)
  5. # 线性归一化
  6. out2 = df.apply(lambda x: ((x.max() - x)/(x.max() - x.min())).round(2))
  7. print('Solution Q2\n', out2)
  • 计算每一行与下一行的相关性
  1. df = pd.DataFrame(np.random.randint(1,100, 25).reshape(5, -1))
  2. # 行与行之间的相关性
  3. [df.iloc[i].corr(df.iloc[i+1]).round(2) for i in range(df.shape[0])[:-1]]
  • 用0赋值dataframe的主对角线和副对角线
  1. df = pd.DataFrame(np.random.randint(1,100, 25).reshape(5, -1))
  2. print(df)
  3. # zhu
  4. for i in range(df.shape[0]):
  5. df.iat[i, i] = 0
  6. df.iat[df.shape[0]-i-1, i] = 0
  7. print(df)
  8. #> 0 1 2 3 4
  9. 0 51 35 71 71 79
  10. 1 78 25 71 85 44
  11. 2 90 97 72 14 4
  12. 3 27 91 37 25 48
  13. 4 1 26 68 70 20
  14. #> 0 1 2 3 4
  15. 0 0 35 71 71 0
  16. 1 78 0 71 0 44
  17. 2 90 97 0 14 4
  18. 3 27 0 37 0 48
  19. 4 0 26 68 70 0
  • 得到按列分组的dataframe的平均值和标准差
  1. df = pd.DataFrame({'col1': ['apple', 'banana', 'orange'] * 2,
  2. 'col2': np.random.randint(0,15,6),
  3. 'col3': np.random.randint(0, 15, 6)})
  4. print(df)
  5. # 按列col1分组后的平均值
  6. df_grouped_mean = df.groupby(['col1']).mean()
  7. print(df_grouped_mean)
  8. # 按列col1分组后的标准差
  9. df_grouped_std = df.groupby(['col1']).mean()
  10. print(df_grouped_std)
  11. #> col1 col2 col3
  12. 0 apple 2 14
  13. 1 banana 11 8
  14. 2 orange 8 10
  15. 3 apple 5 2
  16. 4 banana 6 12
  17. 5 orange 11 13
  18. #> col2 col3
  19. col1
  20. apple 3.5 8.0
  21. banana 8.5 10.0
  22. orange 9.5 11.5
  23. #> col2 col3
  24. col1
  25. apple 3.5 8.0
  26. banana 8.5 10.0
  27. orange 9.5 11.5
  • 如何得到按列分组后另一列的第n大的值
  1. df = pd.DataFrame({'fruit': ['apple', 'banana', 'orange'] * 2,
  2. 'taste': np.random.rand(6),
  3. 'price': np.random.randint(0, 15, 6)})
  4. print(df)
  5. # teste列按fruit分组
  6. df_grpd = df['taste'].groupby(df.fruit)
  7. # teste列中banana元素的信息
  8. x=df_grpd.get_group('banana')
  9. # 排序并找第2大的值
  10. s = x.sort_values().iloc[-2]
  11. print(s)
  12. #> fruit taste price
  13. 0 apple 0.521990 7
  14. 1 banana 0.640444 0
  15. 2 orange 0.460509 9
  16. 3 apple 0.818963 4
  17. 4 banana 0.646138 7
  18. 5 orange 0.917056 12
  19. #> 0.6404436436085967
  • 如何计算分组dataframe的平均值,并将分组列保留为另一列
  1. df = pd.DataFrame({'fruit': ['apple', 'banana', 'orange'] * 2,
  2. 'rating': np.random.rand(6),
  3. 'price': np.random.randint(0, 15, 6)})
  4. # 按fruit分组后,price列的平均值,并将分组置为一列
  5. out = df.groupby('fruit', as_index=False)['price'].mean()
  6. print(out)
  7. #> fruit price
  8. 0 apple 4.0
  9. 1 banana 6.5
  10. 2 orange 11.0
  11. 33.如何获取两列值元素相等的位置(并非索引)
  12. df = pd.DataFrame({'fruit1': np.random.choice(['apple', 'orange', 'banana'], 3),
  13. 'fruit2': np.random.choice(['apple', 'orange', 'banana'], 3)})
  14. print(df)
  15. # 获取两列元素相等的行
  16. np.where(df.fruit1 == df.fruit2)
  17. #> fruit1 fruit2
  18. 0 apple banana
  19. 1 apple apple
  20. 2 orange apple
  21. #> (array([1], dtype=int64),)
  • 如何创建指定列偏移后的新列
  1. df = pd.DataFrame(np.random.randint(1, 100, 20).reshape(-1, 4), columns = list('abcd'))
  2. # 创建往下偏移后的列
  3. df['a_lag1'] = df['a'].shift(1)
  4. # 创建往上偏移后的列
  5. df['b_lead1'] = df['b'].shift(-1)
  6. print(df)
  7. #> a b c d a_lag1 b_lead1
  8. 0 29 90 43 24 NaN 36.0
  9. 1 94 36 67 66 29.0 76.0
  10. 2 81 76 44 49 94.0 97.0
  11. 3 55 97 10 74 81.0 43.0
  12. 4 32 43 62 62 55.0 NaN
  • 如何获得dataframe中单一值的频数
  1. df = pd.DataFrame(np.random.randint(1, 10, 20).reshape(-1, 4), columns = list('abcd'))
  2. # 统计元素值的个数
  3. pd.value_counts(df.values.ravel())
  4. #> 9 3
  5. 7 3
  6. 3 3
  7. 1 3
  8. 6 2
  9. 5 2
  10. 4 2
  11. 8 1
  12. 2 1
  13. dtype: int64
  • 如何将文本拆分为两个单独的列
  1. df = pd.DataFrame(["STD, City State",
  2. "33, Kolkata West Bengal",
  3. "44, Chennai Tamil Nadu",
  4. "40, Hyderabad Telengana",
  5. "80, Bangalore Karnataka"], columns=['row'])
  6. print(df)
  7. # expand=True表示以分割符把字符串分成两列
  8. df_out = df.row.str.split(',|\t', expand=True)
  9. # 获取新的列
  10. new_header = df_out.iloc[0]
  11. # 重新赋值
  12. df_out = df_out[1:]
  13. df_out.columns = new_header
  14. print(df_out)
  15. #> row
  16. 0 STD, City State
  17. 1 33, Kolkata West Bengal
  18. 2 44, Chennai Tamil Nadu
  19. 3 40, Hyderabad Telengana
  20. 4 80, Bangalore Karnataka
  21. #> 0 STD City State
  22. 1 33 Kolkata West Bengal
  23. 2 44 Chennai Tamil Nadu
  24. 3 40 Hyderabad Telengana
  25. 4 80 Bangalore Karnataka
  • 如何构建多级索引的dataframe

我们利用元组(Tuple)构建多级索引,然后定义dataframe.

  1. # 如何构建多级索引的dataframe
  2. # 先通过元组方式构建多级索引
  3. import numpy as np
  4. outside = ['A','A','A','B','B','B']
  5. inside =[1,2,3,1,2,3]
  6. my_index = list(zip(outside,inside))
  7. # my_index
  8. # 转化为pd格式的索引
  9. my_index = pd.MultiIndex.from_tuples(my_index)
  10. # my_index
  11. # 构建多级索引dataframe
  12. df = pd.DataFrame(np.random.randn(6,2),index =my_index,columns=['fea1','fea2'])
  13. df
  14. 多索引dataframe结果:
  15. 获取多索引dataframe的数据:
  16. df.loc['A'].iloc[1]
  17. #> fea1 -0.794461
  18. fea2 0.882104
  19. Name: 2, dtype: float64
  20. df.loc['A'].iloc[1]['fea1']
  21. #> -0.7944609970323794

6. 统计汇总函数

函数

含义

min()

计算最小值

max()

计算最大值

sum()

求和

mean()

计算平均值

count()

计数(统计非缺失元素的个数)

size()

计数(统计所有元素的个数)

median()

计算中位数

var()

计算方差

std()

计算标准差

quantile()

计算任意分位数

cov()

计算协方差

corr()

计算相关系数

skew()

计算偏度

kurt()

计算峰度

mode()

计算众数

describe()

描述性统计(一次性返回多个统计结果)

groupby()

分组

aggregate()

聚合运算(可以自定义统计函数)

argmin()

寻找最小值所在位置

argmax()

寻找最大值所在位置

any()

等价于逻辑“或”

all()

等价于逻辑“与”

value_counts()

频次统计

cumsum()

运算累计和

cumprod()

运算累计积

pct­­_change()

运算比率(后一个元素与前一个元素的比率)

7. 数据清洗函数

函数

含义

duplicated()

判断序列元素是否重复

drop_duplicates()

删除重复值

hasnans()

判断序列是否存在缺失(返回TRUE或FALSE)

isnull()

判断序列元素是否为缺失(返回与序列长度一样的bool值)

notnull()

判断序列元素是否不为缺失(返回与序列长度一样的bool值)

dropna()

删除缺失值

fillna()

缺失值填充

ffill()

前向后填充缺失值(使用缺失值的前一个元素填充)

bfill()

后向填充缺失值(使用缺失值的后一个元素填充)

dtypes()

检查数据类型

astype()

类型强制转换

pd.to_datetime

转日期时间型

factorize()

因子化转换

sample()

抽样

where()

基于条件判断的值替换

replace()

按值替换(不可使用正则)

str.replace()

按值替换(可使用正则)

str.split.str()

字符分隔

8. 数据筛选函数

函数

含义

isin()

成员关系判断

between()

区间判断

loc()

条件判断(可使用在数据框中)

iloc()

索引判断(可使用在数据框中)

compress()

条件判断

nlargest()

搜寻最大的n个元素

nsmallest()

搜寻最小的n个元素

str.findall()

子串查询(可使用正则)

9. 绘图与元素级运算函数

函数

含义

hist()

绘制直方图

plot()

可基于kind参数绘制更多图形(饼图,折线图,箱线图等)

map()

元素映射

apply()

基于自定义函数的元素级操作

10. 时间序列函数

函数

含义

dt.date()

抽取出日期值

dt.time()

抽取出时间(时分秒)

dt.year()

抽取出年

dt.mouth()

抽取出月

dt.day()

抽取出日

dt.hour()

抽取出时

dt.minute()

抽取出分钟

dt.second()

抽取出秒

dt.quarter()

抽取出季度

dt.weekday()

抽取出星期几(返回数值型)

dt.weekday_name()

抽取出星期几(返回字符型)

dt.week()

抽取出年中的第几周

dt.dayofyear()

抽取出年中的第几天

dt.daysinmonth()

抽取出月对应的最大天数

dt.is_month_start()

判断日期是否为当月的第一天

dt.is_month_end()

判断日期是否为当月的最后一天

dt.is_quarter_start()

判断日期是否为当季度的第一天

dt.is_quarter_end()

判断日期是否为当季度的最后一天

dt.is_year_start()

判断日期是否为当年的第一天

dt.is_year_end()

判断日期是否为当年的最后一天

dt.is_leap_year()

判断日期是否为闰年

11. 其它函数

函数

含义

append()

序列元素的追加(需指定其他序列)

diff()

一阶差分

round()

元素的四舍五入

sort_values()

按值排序

sort_index()

按索引排序

to_dict()

转为字典

tolist()

转为列表

unique()

元素排重

参考文献

超全的 100 个 Pandas 函数汇总,建议收藏

非常全面的Pandas入门教程_Summer1Li的博客-CSDN博客_pandas教学

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/爱喝兽奶帝天荒/article/detail/853051?site
推荐阅读
相关标签
  

闽ICP备14008679号