目前从事数据版块的工作,基本就是数仓、ETL、BI这一块。学习了一个python机器学习课程,在此记下学习过程中遇到的坑。pandas的详细使用可查:http://pandas.pydata.org/pandas-docs/stable/index.html
只定义列名
import pandas as pd df = pd.DataFrame(columns=['姓名','年龄','性别']) print(df)输出为: Empty DataFrame Columns: [姓名, 年龄, 性别] Index: []
列名及索引(行名)都定义:
import pandas as pd df = pd.DataFrame(columns=['姓名','年龄','性别'],index=['甲','乙','丙']) print(df)输出为: 姓名 年龄 性别 甲 NaN NaN NaN 乙 NaN NaN NaN 丙 NaN NaN NaN
定义加上值:
import pandas as pd df = pd.DataFrame([['张三',23,'男'],['李四',24,'女'],['王五',35,'男']],columns=['姓名','年龄','性别'],index=['甲','乙','丙']) print(df)输出为: 姓名 年龄 性别 甲 张三 23 男 乙 李四 24 女 丙 王五 35 男
append字典结构
import pandas as pd df = pd.DataFrame(columns=['姓名','年龄','性别']) print(df) line = {'姓名':'张三','年龄':24,'性别':'男'} df = df.append(line,ignore_index=True) print(df)输出为: Empty DataFrame Columns: [姓名, 年龄, 性别] Index: [] 姓名 年龄 性别 0 张三 24 男
append Series结构 方法1:
import pandas as pd df = pd.DataFrame(columns=['姓名','年龄','性别']) print(df) line = pd.Series({'姓名':'张三','年龄':24,'性别':'男'}) df = df.append(line,ignore_index=True) print(df)输出为: Empty DataFrame Columns: [姓名, 年龄, 性别] Index: [] 姓名 年龄 性别 0 张三 24 男
方法2:
import pandas as pd df = pd.DataFrame(columns=['姓名','年龄','性别']) print(df) line = pd.Series({'姓名':'张三','年龄':24,'性别':'男'},name='Series可以设置索引名称') df = df.append(line,ignore_index=False) print(df)输出为: Empty DataFrame Columns: [姓名, 年龄, 性别] Index: [] 姓名 年龄 性别 Series可以设置索引名称 张三 24 男
如果是append字典,则ignore_index必须为True,如果是append Series结构,则可以设置ignore_index为False,然后设置特定的索引。
去除列:
import pandas as pd df = pd.DataFrame([['张三',23,'男'],['李四',24,'女'],['王五',35,'男']],columns=['姓名','年龄','性别'],index=['甲','乙','丙']) print(df) #inplace如果设置为False,则不会替换原有对象 df.drop(columns=['姓名','年龄'],inplace=False) print(df) #列删除 df.drop(columns=['姓名','年龄'],inplace=True) print(df) #行删除 df = pd.DataFrame([['张三',23,'男'],['李四',24,'女'],['王五',35,'男']],columns=['姓名','年龄','性别'],index=['甲','乙','丙']) df.drop(index='甲',inplace=True) print(df)输出为: 姓名 年龄 性别 甲 张三 23 男 乙 李四 24 女 丙 王五 35 男 姓名 年龄 性别 甲 张三 23 男 乙 李四 24 女 丙 王五 35 男 性别 甲 男 乙 女 丙 男 姓名 年龄 性别 乙 李四 24 女 丙 王五 35 男
drop方法,需要留意inplace变量,若要替换则设置为True,columns和index可以通过列表结构或字符串来定位需要删除的列和行。
行删除的方法二:
import pandas as pd df = pd.DataFrame([['张三',23,'男'],['李四',24,'女'],['王五',35,'男']],columns=['姓名','年龄','性别'],index=['甲','乙','丙']) print(df) #isin是获取所有姓名为['张三']的行数据,~是取反的意思。 df = df[~df['姓名'].isin(['张三'])] print(df)输出为: 姓名 年龄 性别 甲 张三 23 男 乙 李四 24 女 丙 王五 35 男 姓名 年龄 性别 乙 李四 24 女 丙 王五 35 男
查看统计详情:
import pandas as pd df = pd.DataFrame([['张三',23,'男'],['李四',24,'女'],['王五',35,'男']],columns=['姓名','年龄','性别'],index=['甲','乙','丙']) print(df) print(df.describe())输出为: 姓名 年龄 性别 甲 张三 23 男 乙 李四 24 女 丙 王五 35 男 年龄 count 3.000000 mean 27.333333 std 6.658328 min 23.000000 25% 23.500000 50% 24.000000 75% 29.500000 max 35.000000
describe方法可以看到数据里面数值类型的基本统计情况。
applymap操作:
import pandas as pd df = pd.DataFrame([4,13,5,38,28,59,24,79],columns=['年龄']) def testApplyMap(age): #小于30的标记为年轻,大于等于30的标记为中年,大于等于60标记为老年 return '老年' if age >= 60 else ('中年' if age >= 30 else '年轻') print(df) print(df.applymap(testApplyMap)) print(df) df = df.applymap(testApplyMap) print(df)输出为: 年龄 0 4 1 13 2 5 3 38 4 28 5 59 6 24 7 79 年龄 0 年轻 1 年轻 2 年轻 3 中年 4 年轻 5 中年 6 年轻 7 老年 年龄 0 4 1 13 2 5 3 38 4 28 5 59 6 24 7 79 年龄 0 年轻 1 年轻 2 年轻 3 中年 4 年轻 5 中年 6 年轻 7 老年
applymap是向方法中传入每一个元素,然后方法返回结果。applymap没有inplace参数,如果要覆盖原对象,需要进行重新赋值操作。
apply操作:
import pandas as pd df = pd.DataFrame({ 's1': [27.93, 58.08, 38.67, 45.83, 70.26, 46.61, 49.73, 34.02, 56.64, 57.28], 's2': [28.18, 50.61, 31.73, 31.48, 55.96, 22.73, 40.47, 42.02, 31.39, 64.21], 's3': [29.39, 51.62, 57.91, 45.94, 53.81, 45.77, 69.13, 28.75, 43.43, 55.7], 's4': [40.52, 48.55, 59.24, 71.21, 58.48, 63.63, 55.16, 34.9, 54, 68.03], 's5': [26.26, 54.03, 49.08, 46.53, 43.23, 56.79, 58.71, 26.43, 44.97, 54.16] }, index = ['05-21', '05-22', '05-23', '05-24', '05-25', '05-26', '05-27', '05-28', '05-29', '05-30']) def testApply(sale): return max(sale) print(df) print(df.apply(testApply)) print(df.apply(testApply,axis=1)) print(df)输出为: s1 s2 s3 s4 s5 05-21 27.93 28.18 29.39 40.52 26.26 05-22 58.08 50.61 51.62 48.55 54.03 05-23 38.67 31.73 57.91 59.24 49.08 05-24 45.83 31.48 45.94 71.21 46.53 05-25 70.26 55.96 53.81 58.48 43.23 05-26 46.61 22.73 45.77 63.63 56.79 05-27 49.73 40.47 69.13 55.16 58.71 05-28 34.02 42.02 28.75 34.90 26.43 05-29 56.64 31.39 43.43 54.00 44.97 05-30 57.28 64.21 55.70 68.03 54.16 s1 70.26 s2 64.21 s3 69.13 s4 71.21 s5 58.71 dtype: float64
05-21 40.52 05-22 58.08 05-23 59.24 05-24 71.21 05-25 70.26 05-26 63.63 05-27 69.13 05-28 42.02 05-29 56.64 05-30 68.03 dtype: float64 s1 s2 s3 s4 s5 05-21 27.93 28.18 29.39 40.52 26.26 05-22 58.08 50.61 51.62 48.55 54.03 05-23 38.67 31.73 57.91 59.24 49.08 05-24 45.83 31.48 45.94 71.21 46.53 05-25 70.26 55.96 53.81 58.48 43.23 05-26 46.61 22.73 45.77 63.63 56.79 05-27 49.73 40.47 69.13 55.16 58.71 05-28 34.02 42.02 28.75 34.90 26.43 05-29 56.64 31.39 43.43 54.00 44.97 05-30 57.28 64.21 55.70 68.03 54.16
apply是想方法里面传入一列或者一行进行运算,axis=0是传入一列,axis=1则传入一行,默认为0。
输出为: 姓名 年龄 性别 甲 张三 23 男 乙 李四 24 女 丙 王五 35 男
DataFrame后面紧接[],则可以获取对应列数据 甲 张三 乙 李四 丙 王五 Name: 姓名, dtype: object
DataFrame后面紧接[][],第一个为列名,第二个为行名 张三
DataFrame的iloc里面对应的是行的默认索引,0代表第一行,1代表第二行,如此类推 姓名 张三 年龄 23 性别 男 Name: 甲, dtype: object
DataFrame的loc里面对应的行名 姓名 张三 年龄 23 性别 男 Name: 甲, dtype: object
获取列后,也是可以通过iloc和loc来获取行数据的 王五 王五
iat可以通过列和行的默认索引来定位数据 张三
方法为pivot_table:
import pandas as pd import numpy as np df = pd.DataFrame([ ['张三','语文',98.], ['张三','体育',60.], ['李四','数学',60.], ['李四','语文',100.], ['王五','数学',89], ['王五','体育',98.] ], columns=['name','course','score']) print(df.pivot_table('score',index='name',columns='course',aggfunc=np.sum,margins=True,fill_value=0))输出为: course 体育 数学 语文 All name 张三 60 0 98 158.0 李四 0 60 100 160.0 王五 98 89 0 187.0 All 158 149 198 505.0
参数说明: data: 创建透视表的dataframe
values: 要聚合的值, optional
index: 要聚合的index
columns: 要聚合的columns
aggfunc:聚合的方式, default numpy.mean
fill_value: 用来替换透视表的缺失值scalar, default None
margins: 添加所有行,列,例如在后面加个“总和”boolean, default False
dropna: 不要包含条目都是NaN的列boolean, default True
margins_name: 行列名称, default ‘All’
空值处理:
import pandas as pd df = pd.DataFrame([23,3,13,None,5],columns=['年龄']) print(df,'\n') #指定填充的值 print(df.fillna(0)) #取对应列的上一行数据 print(df.ffill()) #取对应列的下一行数据 print(df.bfill())输出为: 年龄 0 23.0 1 3.0 2 13.0 3 NaN 4 5.0
年龄 0 23.0 1 3.0 2 13.0 3 0.0 4 5.0 年龄 0 23.0 1 3.0 2 13.0 3 13.0 4 5.0 年龄 0 23.0 1 3.0 2 13.0 3 5.0 4 5.0
多有的空值补充函数都不会覆盖原来对象,需要设置inplace=True参数才能覆盖。
去重:
import pandas as pd df = pd.DataFrame([23,3,3,13,None,5],columns=['年龄']) print(df,'\n') print(df.drop_duplicates()) print(df) df.drop_duplicates(inplace=True) print(df)输出为: 年龄 0 23.0 1 3.0 2 3.0 3 13.0 4 NaN 5 5.0
年龄 0 23.0 1 3.0 3 13.0 4 NaN 5 5.0 年龄 0 23.0 1 3.0 2 3.0 3 13.0 4 NaN 5 5.0 年龄 0 23.0 1 3.0 3 13.0 4 NaN 5 5.0
输出为: <class ‘pandas.core.frame.DataFrame’> id no name SYSTEM_SOURCE 0 1 1 哈哈 Z
参数详情: sql : 要执行的SQL查询。
con : SQLAlchemy可连接(引擎/连接)或数据库字符串URI或DBAPI2连接(后备模式)使用SQLAlchemy可以使用该库支持的任何数据库。如果是DBAPI2对象,则仅支持sqlite3。
index_col : 字符串或字符串列表,可选,默认值:无。要设置为索引的列(MultiIndex)。
coerce_float : boolean,默认为True 尝试将非字符串,非数字对象(如decimal.Decimal)的值转换为浮点,这对SQL结果集很有用。
params : list,tuple或dict,optional,默认值:None 要传递给执行方法的参数列表。用于传递参数的语法取决于数据库驱动程序。检查数据库驱动程序文档,了解支持PEP 249的paramstyle中描述的五种语法样式。例如。对于psycopg2,使用%(name)s所以使用params = {‘name’:‘value’}
parse_dates : list或dict,默认值:None 要解析为日期的列名列表。 在解析字符串时间时格式字符串与strftime兼容的位置的字典,或者在解析整数时间戳的情况下是(D,s,ns,ms,us)之一。{column_name: format string} dict of ,其中arg dict对应于关键字参数。 特别适用于没有本机Datetime支持的数据库,例如SQLite。{column_name: arg dict}pandas.to_datetime() columns : list,默认值:None 从SQL表中选择的列名列表(仅在读取表时使用)。
chunksize : int,默认无 如果指定,则返回一个迭代器,其中chunksize是要包含在每个块中的行数。
去空格:
import pandas as pd s = ' sskc ufss ' s = s.strip() print(s) s = s.lstrip('s') print(s) s = s.rstrip('s') print(s)输出为: sskc ufss kc ufss kc uf
strip、lstrip、rstrip默认是去除空格,可以指定值进行去除。
未完待续,有空更新。。。
