目录:
知道drop函数删除df的行或列数据
知道drop_duplicates函数对df或series进行数据去重
知道unique函数对series进行数据去重
知道apply函数的使用方法
了解numpy.vectorize(func)函数向量化
- import pandas as pd
-
- df = pd.read_csv('../datas/data_set/1960-2019全球GDP数据.csv', encoding='gbk')
- df2 = df.head()
-
- # 拷贝一份df
- df3 = df2.copy()
-
- # 一列数据都是固定值
- df3['new col 1'] = 33
-
- # 新增列数据数量必须和行数相等
- df3['new col 2'] = [1, 2, 3, 4, 5]
- df3['new col 3'] = df3.year * 2
-
- # 分别查看增加数据列之后的df和原df
- print(df3)
- print(df2)
- import pandas as pd
-
- df = pd.read_csv('../datas/data_set/1960-2019全球GDP数据.csv', encoding='gbk')
- df2 = df.head()
-
- # 拷贝一份df
- df3 = df2.copy()
-
- print(df3)
-
- # 默认删除行,按索引值删除,不会在原df上删除,添加参数inplace=True,此时就在原df上进行删除
- df4 = df3.drop([0])
- print(df4)
- # 在原df上进行删除
- df3.drop([0], inplace=True)
- print(df3)
- # 可以删除多行
- df5 = df3.drop([2, 4])
- print(df5)
- # 对series对象按索引值删除
- print(df3.GDP)
-
- df6 = df3.GDP.drop([1, 3])
- print(df6)
df.drop默认删除指定索引值的行 axis=0或axis='index';如果添加参数axis=1 或 axis='columns',则删除指定列名的列
- import pandas as pd
-
- df = pd.read_csv('../datas/data_set/1960-2019全球GDP数据.csv', encoding='gbk')
- df2 = df.head()
-
- # 拷贝一份df
- df3 = df2.copy()
-
- # 一列数据都是固定值
- df3['new col 1'] = 33
-
- # 新增列数据数量必须和行数相等
- df3['new col 2'] = [1, 2, 3, 4, 5]
- df3['new col 3'] = df3.year * 2
-
- print(df3)
-
- df4 = df3.drop(['new col 3'], axis=1)
- print(df4)
运行下面的代码获取具有重复数据的df(代码中使用的append函数会在后边《合并与变形》章节中详细介绍)
- import pandas as pd
-
- df = pd.read_csv('../datas/data_set/1960-2019全球GDP数据.csv', encoding='gbk')
- df2 = df.head()
- print(df2)
-
- df4 = pd.concat([df2] * 2).reset_index(drop=True)
- print(df4)
-
- # 去除重复的数据
- # 默认对所有列进行去重,可以通过参数 subset=['列名1','列名2'...] 对指定的列进行去重
- df5 = df4.drop_duplicates()
- print(df5)
- import pandas as pd
-
- df = pd.read_csv('../datas/data_set/1960-2019全球GDP数据.csv', encoding='gbk')
- df2 = df.head()
- print(df2)
-
- df4 = pd.concat([df2] * 2).reset_index(drop=True)
- print(df4)
-
- # Seriers对象使用drop_duplicates函数进行去重,返回Series对象
- print(df4.country)
- df5 = df4.country.drop_duplicates()
- print(df5)
-
- # Seriers对象还可以使用unique函数进行去重,返回的ndarray数组
- df6 = df4.country.unique()
- print(df6)
- import pandas as pd
-
- df = pd.read_csv('../datas/data_set/1960-2019全球GDP数据.csv', encoding='gbk')
- # 拷贝一份数据
- df5 = df.head().copy()
- print(df5)
-
- df5['GDP'] = [5, 4, 3, 2, 1]
- print(df5)
- import pandas as pd
-
- # 读取数据选取前5行作为一个新的df
- df = pd.read_csv('../datas/data_set/1960-2019全球GDP数据.csv', encoding='gbk')
- df6 = df.head().copy()
- print(df6)
-
- # series对象替换数据,返回的还是series对象,不会对原来的df造成修改
- df7 = df6.year.replace(1960, 19600)
- print(df7)
-
- # 如果加上inplace=True参数,则会修改原始df
- df6.country.replace('日本', '扶桑', inplace=True)
- print(df6)
-
- # df也可以直接调用replace函数,用法和s.replace用法一致,只是返回的是df对象
- df8 = df6.replace(1960, 19600)
- print(df8)
我们可以利用[s对象的判断表达式]来选取df中的数据,再进行赋值修改
- import pandas as pd
-
- # 读取数据选取前5行作为一个新的df
- df = pd.read_csv('../datas/data_set/1960-2019全球GDP数据.csv', encoding='gbk')
- df7 = df.head().copy()
- print(df7)
- # 如果country是日本 那就修改GDP为7777
- df7['GDP'][df7['country'] == '日本'] = 7777
- print(df7)
-
- # 上述步骤解析
- # df7['country'] == '日本'
- # [df7['country'] == '日本']
- # df7['GDP'][df7['country'] == '日本']
.apply()来调用我们自定义的函数- import pandas as pd
-
- # 加载数据,构造示例df对象
- # 读取数据选取前5行作为一个新的df
- df = pd.read_csv('../datas/data_set/1960-2019全球GDP数据.csv', encoding='gbk')
- df8 = df.head()
- print(df8)
-
-
- # Series对象使用apply调用自定义的函数,返回新的Series对象
- # 自定义函数必须接收一个参数
- def foo(x):
- # x此时是s对象中一个数据
- # 本自定义函数返回的也是一个数据
- if x == '美国':
- return '美利坚'
- return x
-
-
- df9 = df8['country'].apply(lambda x: foo(x))
- print(df9)
-
-
- # Series对象使用apply调用自定义的函数,并向自定义函数中传入参数
- # 自定义函数必须接收一个参数
- def foo(x, arg1):
- # x此时是s对象中一个数据
- # 本自定义函数返回的也是一个数据
- if x == '美国':
- return '美利坚'
- return arg1
-
-
- df10 = df8['country'].apply(lambda x: foo(x, arg1='其他国家'))
- print(df10)
- import pandas as pd
-
- # 加载数据,构造示例df对象
- # 读取数据选取前5行作为一个新的df
- df = pd.read_csv('../datas/data_set/1960-2019全球GDP数据.csv', encoding='gbk')
- df8 = df.head()
- print(df8)
-
-
- def foo(s, arg1):
- # 此时s参数就是df中的一列数据,s对象
- # 函数也必须返回一列数据,s对象
- try:
- return s + arg1
- except:
- return s
-
-
- # 返回df对象
- df9 = df8.apply(lambda x: foo(x, arg1=1))
- print(df9)
使用参数axis=1,使df.apply()调用的自定义函数按行执行
- import pandas as pd
-
- # 加载数据,构造示例df对象
- # 读取数据选取前5行作为一个新的df
- df = pd.read_csv('../datas/data_set/1960-2019全球GDP数据.csv', encoding='gbk')
- df8 = df.head()
- print(df8)
-
-
- def foo(s, arg1):
- # 此时s参数就是df中的一行数据,s对象
- # 函数也必须返回一行数据,s对象
- # print(s)
- if s['country'] == arg1:
- s.GDP = 6666
- return s
- return s
-
-
- # 返回df对象
- df9 = df8.apply(lambda x: foo(x, arg1='美国'), axis=1)
- print(df9)
小结:
s.apply(自定义函数名, arg1=xx, ...) 对s对象中的每一个值,都执行自定义函数,且该自定义函数除了固定接收每一个值作为第一参数以外,还可以接收其他自定义参数
df.apply(自定义函数名, arg1=xx, ...) 对df对象中的每一列,都执行自定义函数,且该自定义函数除了固定接收列对象作为第一参数以外,还可以接收其他自定义参数
df.apply(自定义函数名, arg1=xx, ..., axis=1) 对df对象中的每一行,都执行自定义函数,且该自定义函数除了固定接收行对象作为第一参数以外,还可以接收其他自定义参数
运行下面会报错的代码
- import pandas as pd
-
- # 加载数据,构造示例df对象
- # 读取数据选取前5行作为一个新的df
- df = pd.read_csv('../datas/data_set/1960-2019全球GDP数据.csv', encoding='gbk')
- df8 = df.head()
- print(df8)
-
- # 运行下面会报错的代码
- # 构造全是int类型的df
- df9 = df8.drop('country', axis=1)
- print(df9)
-
-
- def bar(s):
- # 此时s参数就是df中的一列数据,s对象
- # 函数也必须返回一列数据,s对象
- if s != 1960:
- return s
- else:
- return s + 1
-
-
- # 报错
- df10 = df9.apply(lambda x: bar(x))
- print(df10)
- # 运行上述代码会报错
上述错误的代码中,if s != 1960:报错,s != 1960 返回一组bool值(向量),这个判断表达式没有问题,但和if连在一起使用就会报错----if只能与返回单一bool值(标量)的判断表达式放在一起;此时我们就需要这个if可以和向量放在一起使用,那么这个时候我们就可以使用函数向量化:让整个函数中原来不能和向量进行操作的代码变为可以和向量进行操作【这段话啥意思不理解也没关系,看下边的代码】
- import pandas as pd
- import numpy as np
-
- # 加载数据,构造示例df对象
- # 读取数据选取前5行作为一个新的df
- df = pd.read_csv('../datas/data_set/1960-2019全球GDP数据.csv', encoding='gbk')
- df8 = df.head()
- print(df8)
-
- # 构造全是int类型的df
- df9 = df8.drop('country', axis=1)
- print(df9)
-
-
- def bar(s):
- # 此时s参数就是df中的一列数据,s对象
- # 函数也必须返回一列数据,s对象
- if s != 1960:
- return s
- else:
- return s + 1
-
-
- # 对原来的bar函数执行np.vectorize(),返回新的函数bar2
- bar2 = np.vectorize(lambda x: bar(x))
-
- # 再使用新的bar2函数
- df10 = df9.apply(bar2)
- print(df10)
还可以利用装饰器对函数进行向量化
- import pandas as pd
- import numpy as np
-
- # 加载数据,构造示例df对象
- # 读取数据选取前5行作为一个新的df
- df = pd.read_csv('../datas/data_set/1960-2019全球GDP数据.csv', encoding='gbk')
- df8 = df.head()
- print(df8)
-
- # 构造全是int类型的df
- df9 = df8.drop('country', axis=1)
- print(df9)
-
-
- # 使用装饰器
- @np.vectorize
- def bar(s):
- # 此时s参数就是df中的一列数据,s对象
- # 函数也必须返回一列数据,s对象
- if s != 1960:
- return s
- else:
- return s + 1
-
-
- # 再使用被向量化装饰器装饰的bar函数
- df10 = df9.apply(bar)
- print(df10)
df['列名'] = 标量或向量 修改或添加列
根据索引删除行数据
df.drop([列名1, 列名2, ...], axis=1) 根据列名删除列数据
df或s对象去除重复的行数据
s.unique() s对象去除重复的数据
替换数据
df或series对象替换数据,返回的还是原来相同类型的对象,不会对原来的df造成修改
如果加上inplace=True参数,则会修改原始df
df['指定列'][df['列名']=='x'] = y 按条件df['列名']=='x'返回True的对应行的指定列的值修改为y
apply函数
s.apply(自定义函数名, arg1=xx, ...) 对s对象中的每一个值,都执行自定义函数,且该自定义函数除了固定接收每一个值作为第一参数以外,还可以接收其他自定义参数
df.apply(自定义函数名, arg1=xx, ...) 对df对象中的每一列,都执行自定义函数,且该自定义函数除了固定接收列对象作为第一参数以外,还可以接收其他自定义参数
df.apply(自定义函数名, arg1=xx, ..., axis=1) 对df对象中的每一行,都执行自定义函数,且该自定义函数除了固定接收行对象作为第一参数以外,还可以接收其他自定义参数
new_func = numpy.vectorize(func) 函数向量化,返回一个新的函数