目录
5.2.3 fillna(method='ffill'或者'bfill')向下或者向上填充
5.2.6向上填充方法:bfill()和backfill()
5.5.1统计Series每个元素中某个字符出现的次数str.count()
5.5.2值转成大写str.upper()、转成小写str.lower()
5.5.4以某个字符串开头str.startswith()和以某个字符串结尾str.endswith()
1.函数的映射:
1.1apply()
用于对DataFrame中的数据按行或者按列操作
1.1.1使用自定义函数
import numpy as np
import pandas as pd
df = pd.DataFrame(np.random.randint(20,size=(4,3)),columns=list('bde'),
index=['Shenzhen','Beijing','Changsha','Shanghai'])
print('df原始数据:')
print(df)
print('使用自定义函数:')
# x是参数,:后面是返回值
f = lambda x:x.max()-x.min()
#apply()默认0轴
print('apply()默认0轴:')
apply_df = df.apply(f)
print(apply_df)
#apply(),操作1轴
print('apply()操作1轴:')
apply_df = df.apply(f,axis=1)
print(apply_df)
运行结果:
df原始数据:
b d e
Shenzhen 19 8 6
Beijing 3 6 4
Changsha 14 19 7
Shanghai 19 2 11
使用自定义函数:
apply()默认0轴:
b 16
d 17
e 7
dtype: int32
apply()操作1轴:
Shenzhen 13
Beijing 3
Changsha 12
Shanghai 17
dtype: int32
1.1.2使用内置函数
import numpy as np
import pandas as pd
df = pd.DataFrame(np.random.randint(20,size=(4,3)),columns=list('bde'),
index=['Shenzhen','Beijing','Changsha','Shanghai'])
print('df原始数据:')
print(df)
print('使用内置函数:')
# 使用内置函数np.sqrt()
apply_df = df.loc[:,'b'].apply(np.sqrt)
print(apply_df)
运行结果:
df原始数据:
b d e
Shenzhen 9 5 6
Beijing 13 9 8
Changsha 8 11 9
Shanghai 19 15 1
使用内置函数:
Shenzhen 3.000000
Beijing 3.605551
Changsha 2.828427
Shanghai 4.358899
Name: b, dtype: float64
1.1.3apply()生活案例-计算税额
import pandas as pd
data = {'商品名称': ['商品A', '商品B', '商品C', '商品D'],
'销售价格': [20.0, 15.0, 30.0, 25.0]}
df = pd.DataFrame(data)
print('df原始数据:')
print(df)
print('apply()生活案例-计算税额:')
df['税额1'] = df['销售价格'].apply(lambda x:x*0.1)
# 或者
df['税额2'] = df['销售价格']*0.1
print(df)
#使用自定义函数
def fun(x):
return pd.Series([x.min(),x.max()],index=['min','max'])
df = df.apply(fun)
print(df)
运行结果:
df原始数据:
商品名称 销售价格
0 商品A 20.0
1 商品B 15.0
2 商品C 30.0
3 商品D 25.0
apply()生活案例-计算税额:
商品名称 销售价格 税额1 税额2
0 商品A 20.0 2.0 2.0
1 商品B 15.0 1.5 1.5
2 商品C 30.0 3.0 3.0
3 商品D 25.0 2.5 2.5
商品名称 销售价格 税额1 税额2
min 商品A 15.0 1.5 1.5
max 商品D 30.0 3.0 3.0
1.2map()
和apply()类型,只是map()是用于对Series中的每一个数据操作
import pandas as pd
s = pd.Series(['apple', 'banana', 'carrot', 'apple', 'banana', 'carrot'])
price = {'apple': 5.0, 'banana': 2.5, 'carrot': 1.2}
print('s原始数据:')
print(s)
# map()映射price后的df数据
print('map()映射price后的数据:')
map_s = s.map(price)
print(map_s)
df = pd.DataFrame(['apple', 'banana', 'carrot', 'apple', 'banana', 'carrot'],columns=['fruit'])
price = {'apple': 5.0, 'banana': 2.5, 'carrot': 1.2}
print('df原始数据:')
print(df)
# map()映射price后的df数据
print('map()映射price后的df数据:')
df['price'] = df['fruit'].map(price)
print(df)
运行结果:
s原始数据:
0 apple
1 banana
2 carrot
3 apple
4 banana
5 carrot
dtype: object
map()映射price后的数据:
0 5.0
1 2.5
2 1.2
3 5.0
4 2.5
5 1.2
dtype: float64
df原始数据:
fruit
0 apple
1 banana
2 carrot
3 apple
4 banana
5 carrot
map()映射price后的df数据:
fruit price
0 apple 5.0
1 banana 2.5
2 carrot 1.2
3 apple 5.0
4 banana 2.5
5 carrot 1.2
2.判断是否是唯一索引df.index.is_unique
import pandas as pd
# 示例1:检查DataFrame索引的唯一性
df = pd.DataFrame({'A': [1, 2, 3]}, index=['a', 'b', 'c'])
print(df.index.is_unique) # 输出:True
# 示例2:检查Series索引的唯一性
s = pd.Series([1, 2, 3], index=['a', 'b', 'c'])
print(s.index.is_unique) # 输出:True
# 示例3:检查具有重复索引的DataFrame索引的唯一性
df_duplicate_index = pd.DataFrame({'A': [1, 2, 3]}, index=['a', 'b', 'a'])
print(df_duplicate_index.index.is_unique) # 输出:False
运行结果:
True
True
False
3.获取唯一索引df.index.unique()
import pandas as pd
# 示例1:获取DataFrame索引的唯一值
df = pd.DataFrame({'A': [1, 2, 3]}, index=['a', 'b', 'c'])
print(df.index.unique())
# 示例2:获取DataFrame索引的唯一值
df_duplicate_index = pd.DataFrame({'A': [1, 2, 3]}, index=['a', 'b', 'a'])
print(df_duplicate_index.index.unique())
运行结果:
Index(['a', 'b', 'c'], dtype='object')
Index(['a', 'b'], dtype='object')
4.汇总和计算
import pandas as pd
data = {'姓名': ['Lcuy', 'Lily', 'Tom', 'Jack'],
'数学': [85, 92, 78, 65],
'英语': [76, 88, 92, 71],
'历史': [90, 82, 68, 56]}
df = pd.DataFrame(data)
print('df原始数据:')
print(df)
print('设置姓名为索引:')
df.set_index('姓名',inplace=True)
print(df)
print('每个人的平均成绩:')
print(df.mean(axis=1))
print('每科最高分是谁:')
print(df.idxmax())
print('每科最低分是谁:')
print(df.idxmin())
运行结果:
df原始数据:
姓名 数学 英语 历史
0 Lcuy 85 76 90
1 Lily 92 88 82
2 Tom 78 92 68
3 Jack 65 71 56
设置姓名为索引:
数学 英语 历史
姓名
Lcuy 85 76 90
Lily 92 88 82
Tom 78 92 68
Jack 65 71 56
每个人的平均成绩:
姓名
Lcuy 83.666667
Lily 87.333333
Tom 79.333333
Jack 64.000000
dtype: float64
每科最高分是谁:
数学 Lily
英语 Tom
历史 Lcuy
dtype: object
每科最低分是谁:
数学 Jack
英语 Jack
历史 Jack
dtype: object
5.数据处理
5.1删除空值:dropna()
"""
DataFrame.dropna(axis=0, how='any', thresh=None, subset=None, inplace=False, ignore_index=False)
参数说明:
axis:要应用dropna的轴,0表示行,1表示列,默认0
how: 'any'或'all'。'any'表示该行或列中任何一个NaN就drop;'all'表示全为NaN才drop,默认any
thresh:允许最大保留的NaN个数,超过则drop
subset: 指定要检查NaN的列
inplace: 是否在原对象上进行操作,默认False
ignore_index:默认False保留原索引,为True会忽略原索引
返回值:
根据参数inplace,如果inplace=False返回新的DataFrame,如果inplace=True在原DataFrame上操作。
"""
5.1.1只要有空值就删除整行:
import pandas as pd
from numpy import nan as NaN
df1 = pd.DataFrame([[1, 2, 3], [NaN, 5, NaN], [NaN, 9, 8], [NaN, NaN, NaN]])
print(df1)
print('*' * 20)
print('默认对行操作(axis=0),只要有空值就删除整行:')
print(df1.dropna())
运行结果:
0 1 2
0 1.0 2.0 3.0
1 NaN 5.0 NaN
2 NaN 9.0 8.0
3 NaN NaN NaN
********************
默认对行操作(axis=0),只要有空值就删除整行:
0 1 2
0 1.0 2.0 3.0
5.1.2该行都为空值时才删除
import pandas as pd
from numpy import nan as NaN
df1 = pd.DataFrame([[1, 2, 3], [NaN, 5, NaN], [NaN, 9, 8], [NaN, NaN, NaN]],index=list('abcd'))
print(df1)
print('*' * 20)
print('该行都为空值时才删除,忽略索引:')
print(df1.dropna(how='all',ignore_index=True))
运行结果:
0 1 2
a 1.0 2.0 3.0
b NaN 5.0 NaN
c NaN 9.0 8.0
d NaN NaN NaN
********************
该行都为空值时才删除:
0 1 2
0 1.0 2.0 3.0
1 NaN 5.0 NaN
2 NaN 9.0 8.0
5.1.3删除全为空的列
import pandas as pd
from numpy import nan as NaN
df1 = pd.DataFrame([[NaN, 2, 3], [NaN, 5, NaN], [NaN, 9, 8], [NaN, NaN, NaN]],index=list('abcd'))
print(df1)
print('*' * 20)
print('该列都为空值时才删除:')
print(df1.dropna(how='all',axis=1))
运行结果:
0 1 2
a NaN 2.0 3.0
b NaN 5.0 NaN
c NaN 9.0 8.0
d NaN NaN NaN
********************
该列都为空值时才删除:
1 2
a 2.0 3.0
b 5.0 NaN
c 9.0 8.0
d NaN NaN
5.1.4保留至少n个非空值的行
import pandas as pd
from numpy import nan as NaN
df1 = pd.DataFrame([[NaN, 2, 3], [NaN, 5, NaN], [NaN, 9, 8], [NaN, NaN, NaN]],index=list('abcd'))
print(df1)
print('*' * 20)
print('保留至少2个非空值的行:')
print(df1.dropna(thresh=2))
运行结果:
0 1 2
a NaN 2.0 3.0
b NaN 5.0 NaN
c NaN 9.0 8.0
d NaN NaN NaN
********************
保留至少2个非空值的行:
0 1 2
a NaN 2.0 3.0
c NaN 9.0 8.0
5.2填充空值:fillna()
"""
DataFrame.fillna(value=None, method=None, axis=None, inplace=False, limit=None, downcast=None)
参数说明:
value: 要填充的值,可以是标量、字典、Series或DataFrame。默认为None。
method: 填充缺失值的方法,可选值为{'backfill', 'bfill', 'pad', 'ffill', None}。'backfill'或'bfill'表示使用后面的值进行填充,'pad'或'ffill'表示使用前面的值进行填充,None表示不使用任何方法填充。默认为None。
axis: 要填充的轴,可选值为{0, 1, 'index', 'columns'}。0或'index'表示按行填充,1或'columns'表示按列填充。默认为None,表示自动选择。
inplace: 是否在原对象上进行操作,如果设置为True,则在原对象上进行填充,返回None。如果设置为False,则返回填充后的新对象。默认为False。
limit: 限制每个轴上填充缺失值的数量,可以是整数或字典。默认为None。
downcast: 用于降低填充后数据类型的选项,可选值为{'infer', None}。'infer'表示尝试降低到最适合的数据类型,None表示不进行降低。默认为None。
返回值:
根据参数inplace,如果inplace=False返回填充后的新DataFrame或Series,如果inplace=True在原对象上进行填充,返回None。
"""
5.2.1用0填充空值
import pandas as pd
from numpy import nan as NaN
df1 = pd.DataFrame([[1, 2, 3], [NaN, 5, NaN], [NaN, 9, 8], [NaN, NaN, NaN]],index=list('abcd'))
print('df1原始数据:')
print(df1)
print('*' * 20)
print('用0填充空值:')
print(df1.fillna(0))
运行结果:
df1原始数据:
0 1 2
a 1.0 2.0 3.0
b NaN 5.0 NaN
c NaN 9.0 8.0
d NaN NaN NaN
********************
用0填充空值:
0 1 2
a 1.0 2.0 3.0
b 0.0 5.0 0.0
c 0.0 9.0 8.0
d 0.0 0.0 0.0
5.2.2每列空值填充字典中对应的值
import pandas as pd
from numpy import nan as NaN
df1 = pd.DataFrame([[1, 2, 3], [NaN, 5, NaN], [NaN, 9, 8], [NaN, NaN, NaN]],columns=list('abc'))
print('df1原始数据:')
print(df1)
print('*' * 20)
print('每列分别用0、5、10填充:')
df1.fillna({'a':0,'b':5,'c':10},inplace=True)
print(df1)
运行结果:
df1原始数据:
a b c
0 1.0 2.0 3.0
1 NaN 5.0 NaN
2 NaN 9.0 8.0
3 NaN NaN NaN
********************
每列分别用0、5、10填充:
a b c
0 1.0 2.0 3.0
1 0.0 5.0 10.0
2 0.0 9.0 8.0
3 0.0 5.0 10.0
5.2.3 fillna(method='ffill'或者'bfill')向下或者向上填充
import pandas as pd
from numpy import nan as NaN
df1 = pd.DataFrame([[1, 2, 3], [NaN, 5, NaN], [NaN, 9, 8], [10, NaN, NaN]],columns=list('abc'))
print('df1原始数据:')
print(df1)
print('*' * 20)
print('使用前一个非空值填充接下来连续的空值:')
df = df1.fillna(method='ffill')
print(df)
print('*' * 20)
print('使用后一个非空值填充上面连续的空值:')
df = df1.fillna(method='bfill')
print(df)
运行结果:
df1原始数据:
a b c
0 1.0 2.0 3.0
1 NaN 5.0 NaN
2 NaN 9.0 8.0
3 10.0 NaN NaN
********************
使用前一个非空值填充接下来连续的空值:
a b c
0 1.0 2.0 3.0
1 1.0 5.0 3.0
2 1.0 9.0 8.0
3 10.0 9.0 8.0
********************
使用后一个非空值填充上面连续的空值:
a b c
0 1.0 2.0 3.0
1 10.0 5.0 8.0
2 10.0 9.0 8.0
3 10.0 NaN NaN
5.2.4使用每列平均值填充空值
import pandas as pd
from numpy import nan as NaN
df1 = pd.DataFrame([[1, 2, 3], [NaN, 5, NaN], [NaN, 9, 8], [10, NaN, NaN]],columns=list('abc'))
print('df1原始数据:')
print(df1)
print('*' * 20)
print('使用每列平均值填充空值:')
df1.fillna(df1.mean(),inplace=True)
print(df1)
运行结果:
df1原始数据:
a b c
0 1.0 2.0 3.0
1 NaN 5.0 NaN
2 NaN 9.0 8.0
3 10.0 NaN NaN
********************
使用每列平均值填充空值:
a b c
0 1.0 2.000000 3.0
1 5.5 5.000000 5.5
2 5.5 9.000000 8.0
3 10.0 5.333333 5.5
5.2.5向下填充方法:ffill()和pad()
import pandas as pd
from numpy import nan as NaN
df1 = pd.DataFrame([[1, 2, 3], [NaN, 5, NaN], [NaN, 9, 8], [10, NaN, NaN]],columns=list('abc'))
print('df1原始数据:')
print(df1)
print('*' * 20)
print('使用向下填充空值:')
# 方法一:
# df1.ffill(inplace=True)
# print(df1)
# 或者
#方法二,会提示使用ffill()方法:
df1.pad(inplace=True)
print(df1)
运行结果:
df1原始数据:
a b c
0 1.0 2.0 3.0
1 NaN 5.0 NaN
2 NaN 9.0 8.0
3 10.0 NaN NaN
********************
使用向下填充空值:
df1.pad(inplace=True)
a b c
0 1.0 2.0 3.0
1 1.0 5.0 3.0
2 1.0 9.0 8.0
3 10.0 9.0 8.0
5.2.6向上填充方法:bfill()和backfill()
import pandas as pd
from numpy import nan as NaN
df1 = pd.DataFrame([[1, 2, 3], [NaN, 5, NaN], [NaN, 9, 8], [10, NaN, NaN]],columns=list('abc'))
print('df1原始数据:')
print(df1)
print('*' * 20)
print('使用向下填充空值:')
# 方法一:
# df1.bfill(inplace=True)
# print(df1)
# 或者
#方法二,会提示使用bfill()方法:
df1.backfill(inplace=True)
print(df1)
运行结果:
df1原始数据:
df1.backfill(inplace=True)
a b c
0 1.0 2.0 3.0
1 NaN 5.0 NaN
2 NaN 9.0 8.0
3 10.0 NaN NaN
********************
使用向下填充空值:
a b c
0 1.0 2.0 3.0
1 10.0 5.0 8.0
2 10.0 9.0 8.0
3 10.0 NaN NaN
5.3重复值
5.3.1去重:drop_duplicates()
import pandas as pd
s = pd.Series(list('aaabbbbccde'))
print('s原始数据:')
print(s)
print('*'*20)
print('s删除重复数据:')
s.drop_duplicates(inplace=True)
print(s)
print('*'*20)
df = pd.DataFrame({'A':[1,1,1,2,2,3,4,1],'B':list('aaabbcdu')})
print('df原始数据:')
print(df)
print('*'*20)
print('df删除重复的行:')
df.drop_duplicates(inplace=True)
print(df)
运行结果:
s原始数据:
0 a
1 a
2 a
3 b
4 b
5 b
6 b
7 c
8 c
9 d
10 e
dtype: object
********************
s删除重复数据:
0 a
3 b
7 c
9 d
10 e
dtype: object
********************
df原始数据:
A B
0 1 a
1 1 a
2 1 a
3 2 b
4 2 b
5 3 c
6 4 d
7 1 u
********************
df删除重复的行:
A B
0 1 a
3 2 b
5 3 c
6 4 d
7 1 u
5.3.2统计重复次数:value_counts()
import pandas as pd
s = pd.Series(list('aaabbbbccde'))
print('s原始数据:')
print(s)
print('*'*20)
print('s中重复数据次数:')
print(s.value_counts())
print('*'*20)
df = pd.DataFrame({'A':[1,1,1,2,2,3,4,1],'B':list('aaabbcdu')})
print('df原始数据:')
print(df)
print('*'*20)
print('df重复行出现的次数:')
print(df.value_counts())
运行结果:
s原始数据:
0 a
1 a
2 a
3 b
4 b
5 b
6 b
7 c
8 c
9 d
10 e
dtype: object
********************
s中重复数据次数:
b 4
a 3
c 2
d 1
e 1
Name: count, dtype: int64
********************
df原始数据:
A B
0 1 a
1 1 a
2 1 a
3 2 b
4 2 b
5 3 c
6 4 d
7 1 u
********************
df重复行出现的次数:
A B
1 a 3
2 b 2
1 u 1
3 c 1
4 d 1
Name: count, dtype: int64
5.4替换:replace()
5.4.1普通替换replace(旧值,新值)
import pandas as pd
s = pd.Series(list('aaabbbbccde'))
print('s原始数据:')
print(s)
print('*'*20)
print('s替换后的数据:')
s.replace('a','帅',inplace=True)
print(s)
print('*'*20)
df = pd.DataFrame({'A':[1,1,1,2,2,3,4,1],'B':list('aaabbcdu')})
print('df原始数据:')
print(df)
print('*'*20)
print('df替换后的数据:')
df['B'].replace('b','uuu',inplace=True)
print(df)
运行结果:
s原始数据:
0 a
1 a
2 a
3 b
4 b
5 b
6 b
7 c
8 c
9 d
10 e
dtype: object
********************
s替换后的数据:
0 帅
1 帅
2 帅
3 b
4 b
5 b
6 b
7 c
8 c
9 d
10 e
dtype: object
********************
df原始数据:
A B
0 1 a
1 1 a
2 1 a
3 2 b
4 2 b
5 3 c
6 4 d
7 1 u
********************
df替换后的数据:
A B
0 1 a
1 1 a
2 1 a
3 2 uuu
4 2 uuu
5 3 c
6 4 d
7 1 u
5.4.2使用字典替换不同的值
import pandas as pd
s = pd.Series(list('aaabbbbccde'))
print('s原始数据:')
print(s)
print('*'*20)
print('s替换后的数据:')
s.replace({'a':'python','b':'java'},inplace=True)
print(s)
print('*'*20)
df = pd.DataFrame({'A':[1,1,1,2,2,3,4,1],'B':list('aaabbcdu')})
print('df原始数据:')
print(df)
print('*'*20)
print('df替换后的数据:')
df['B'].replace({'a':'python','b':'java'},inplace=True)
print(df)
运行结果:
s原始数据:
0 a
1 a
2 a
3 b
4 b
5 b
6 b
7 c
8 c
9 d
10 e
dtype: object
********************
s替换后的数据:
0 python
1 python
2 python
3 java
4 java
5 java
6 java
7 c
8 c
9 d
10 e
dtype: object
********************
df原始数据:
A B
0 1 a
1 1 a
2 1 a
3 2 b
4 2 b
5 3 c
6 4 d
7 1 u
********************
df替换后的数据:
A B
0 1 python
1 1 python
2 1 python
3 2 java
4 2 java
5 3 c
6 4 d
7 1 u
5.5str属性
前提是元素是字符串,其中的方法类似于处理普通字符串
5.5.1统计Series每个元素中某个字符出现的次数str.count()
import pandas as pd
s = pd.Series(list('aaabbbbccde'))
print('s原始数据:')
print(s)
print('*'*20)
print('a在s中每个元素出现的次数:')
print(s.str.count('a'))
运行结果:
s原始数据:
0 a
1 a
2 a
3 b
4 b
5 b
6 b
7 c
8 c
9 d
10 e
dtype: object
********************
a在s中每个元素出现的次数:
0 1
1 1
2 1
3 0
4 0
5 0
6 0
7 0
8 0
9 0
10 0
dtype: int64
5.5.2值转成大写str.upper()、转成小写str.lower()
import pandas as pd
df = pd.DataFrame({'k1': list('abcDEF'),
'k2': ['h', 'haha', ' six', ' star', np.nan, '123']}
)
print('df原始数据:')
print(df)
print('*'*20)
print('把k1列值转换成大写后赋给k3新列:')
df['k3']=df['k1'].str.upper()
print(df)
print('*'*20)
print('把k1列值转换成大写后赋给k4新列:')
df['k4']=df['k1'].str.lower()
print(df)
运行结果:
df原始数据:
k1 k2
0 a h
1 b haha
2 c six
3 D star
4 E NaN
5 F 123
********************
把k1列值转换成大写后赋给k3新列:
k1 k2 k3
0 a h A
1 b haha B
2 c six C
3 D star D
4 E NaN E
5 F 123 F
********************
把k1列值转换成大写后赋给k4新列:
k1 k2 k3 k4
0 a h A a
1 b haha B b
2 c six C c
3 D star D d
4 E NaN E e
5 F 123 F f
5.5.3统计每个元素的长度:
df = pd.DataFrame({'k1': list('abcDEF'),
'k2': [123, 'haha', ' six', ' star', np.nan, '123']}
)
print('df原始数据:')
print(df)
print('*'*20)
print('统计k2每个元素长度:')
print(df['k2'].str.len())
运行结果:
df原始数据:
k1 k2
0 a 123
1 b haha
2 c six
3 D star
4 E NaN
5 F 123
********************
统计k2每个元素长度:
0 NaN
1 4.0
2 4.0
3 5.0
4 NaN
5 3.0
Name: k2, dtype: float64
5.5.4以某个字符串开头str.startswith()和以某个字符串结尾str.endswith()
参数na=False表示把空值设置为False
df = pd.DataFrame({'k1': ['haha', '456', ' four', ' starts', np.nan, '667'],
'k2': ['123', 'haha', ' six', ' star', np.nan, '123']}
)
print('df原始数据:')
print(df)
print('*'*20)
print('查找k1以ha开头的行:')
con = df['k1'].str.startswith('ha',na=False)
print(con)
print(df[con])
print('*'*20)
print('查找k2以23结尾的行:')
con = df['k2'].str.endswith('23',na=False)
print(con)
print(df[con])
运行结果:
df原始数据:
k1 k2
0 haha 123
1 456 haha
2 four six
3 starts star
4 NaN NaN
5 667 123
********************
查找k1以ha开头的行:
0 True
1 False
2 False
3 False
4 False
5 False
Name: k1, dtype: bool
k1 k2
0 haha 123
********************
查找k2以23结尾的行:
0 True
1 False
2 False
3 False
4 False
5 True
Name: k2, dtype: bool
k1 k2
0 haha 123
5 667 123
5.5.5替换str.replace()
df = pd.DataFrame({'k1 A ': ['haha', '456', ' four', ' starts', np.nan, '667'],
'k2 B ': ['123', 'haha', ' six', ' star', 'six', '123']}
)
print('df原始数据:')
print(df)
print('*'*20)
print('替换列名:')
df.columns = df.columns.str.replace(' ','_')
print(df)
print('*'*20)
print('替换元素值:')
df['k2_B_'] = df['k2_B_'].str.replace('si','zhangsan')
print(df)
运行结果:
df原始数据:
k1 A k2 B
0 haha 123
1 456 haha
2 four six
3 starts star
4 NaN six
5 667 123
********************
替换列名:
k1_A_ k2_B_
0 haha 123
1 456 haha
2 four six
3 starts star
4 NaN six
5 667 123
********************
替换元素值:
k1_A_ k2_B_
0 haha 123
1 456 haha
2 four zhangsanx
3 starts star
4 NaN zhangsanx
5 667 123
5.5.6拆分str.split()
import numpy as np
import pandas as pd
# Series的split
s = pd.Series(['a,b,c,d', '1, 2, 3', np.nan, ['a,a,a,']])
print('s原始数据:')
print(s)
print('*' * 20)
print('以,拆分每个元素:')
print(s.str.split(','))
print('*' * 20)
print('取拆分后的第二个元素:')
print(s.str.split(',')[1]) #取整个分割的第二个单元格
print('*' * 20)
print('取拆分后每个单元格的第三个元素:')
print(s.str.split(',').str[2]) #str定位到单元格,取单元格内的第三个元素
print('*' * 20)
print('拆分后展开:')
print(s.str.split(',',expand=True))
运行结果:
s原始数据:
0 a,b,c,d
1 1, 2, 3
2 NaN
3 [a,a,a,]
dtype: object
********************
以,拆分每个元素:
0 [a, b, c, d]
1 [1, 2, 3]
2 NaN
3 NaN
dtype: object
********************
取拆分后的第二个元素:
['1', ' 2', ' 3']
********************
取拆分后每个单元格的第三个元素:
0 c
1 3
2 NaN
3 NaN
dtype: object
********************
拆分后展开:
0 1 2 3
0 a b c d
1 1 2 3 None
2 NaN NaN NaN NaN
3 NaN NaN NaN NaN
5.5.7生活小案例
import pandas as pd
data = {'姓名': ['lily Smith', 'lucy Johnson', 'jack Brown', 'tom Lee'],
'入职日期': ['2022-05-15', '2020-10-01', '2019-07-20', '2023-03-10']}
df = pd.DataFrame(data)
print('df原始数据:')
print(df)
print('*'*50)
print('拆分姓名,并把名首字母大写:')
df['名'] = df['姓名'].str.split(' ').str[0].str.capitalize()
df['姓'] = df['姓名'].str.split(' ').str[1]
print(df)
运行结果:
df原始数据:
姓名 入职日期
0 lily Smith 2022-05-15
1 lucy Johnson 2020-10-01
2 jack Brown 2019-07-20
3 tom Lee 2023-03-10
**************************************************
拆分姓名,并把名首字母大写:
姓名 入职日期 名 姓
0 lily Smith 2022-05-15 Lily Smith
1 lucy Johnson 2020-10-01 Lucy Johnson
2 jack Brown 2019-07-20 Jack Brown
3 tom Lee 2023-03-10 Tom Lee
5.6分组统计
5.6.1groupby()
import pandas as pd
df = pd.DataFrame({'name': ['BOSS', 'Lilei', 'Lilei', 'Han', 'BOSS', 'BOSS', 'Han', 'BOSS'],
'Year': [2020, 2020, 2020, 2020, 2021, 2021, 2021, 2021],
'salary': [999999, 20000, 25000, 5000, 9999999, 999999, 7500, 999999],
'Bonus': [100000, 20000, 20000, 5000, 200000, 300000, 3000, 400000]})
print('df原始数据:')
print(df)
print('*' * 50)
print('以name分组,统计每个name出现次数:')
print(df.groupby('name').count())
print(df.loc[:, ['name', 'salary', 'Bonus']].groupby('name').mean())
print('*' * 50)
data = {
'Category': ['A', 'A', 'B', 'B', 'A', 'B'],
'Value': [1, 2, 3, 4, 5, 6]}
df = pd.DataFrame(data)
print('df原始数据:')
print(df)
print('*'*60)
print('以Category分组,统计总和、最小值、最大值、平均值、中位数、标准差:')
print(df.groupby('Category').agg({'Value':['sum','min','max','mean','median','std']}))
运行结果:
df原始数据:
name Year salary Bonus
0 BOSS 2020 999999 100000
1 Lilei 2020 20000 20000
2 Lilei 2020 25000 20000
3 Han 2020 5000 5000
4 BOSS 2021 9999999 200000
5 BOSS 2021 999999 300000
6 Han 2021 7500 3000
7 BOSS 2021 999999 400000
**************************************************
以name分组,统计每个name出现次数:
Year salary Bonus
name
BOSS 4 4 4
Han 2 2 2
Lilei 2 2 2
salary Bonus
name
BOSS 3249999.0 250000.0
Han 6250.0 4000.0
Lilei 22500.0 20000.0
**************************************************
df原始数据:
Category Value
0 A 1
1 A 2
2 B 3
3 B 4
4 A 5
5 B 6
************************************************************
以Category分组,统计总和、最小值、最大值、平均值、中位数、标准差:
Value
sum min max mean median std
Category
A 8 1 5 2.666667 2.0 2.081666
B 13 3 6 4.333333 4.0 1.527525
5.6.2生活案例
import numpy as np
import pandas as pd
"""
#按产品分组并计算销售总额和销售数量
#查找每个产品订单的最早日期和最晚日期
"""
data = {
'OrderNumber': [101, 102, 103, 104, 105],
'Date': ['2023-10-01', '2023-10-01', '2023-10-02', '2023-10-03', '2023-10-03'],
'Product': ['笔记本', '鼠标', '键盘', '笔记本', '显示器'],
'Quantity': [2, 5, 3, 1, 2],
'Amount': [2000, 50, 150, 1000, 400]
}
df = pd.DataFrame(data)
print(df)
print('*'*60)
#按产品分组并计算销售总额和销售数量
print(df.loc[:,['Product','Quantity','Amount']].groupby('Product').sum())
print('*'*60)
#查找每个产品订单的最早日期和最晚日期
print(df.loc[:,['Product','Date']].groupby('Product').agg({'Date':['min','max']}))
运行结果:
OrderNumber Date Product Quantity Amount
0 101 2023-10-01 笔记本 2 2000
1 102 2023-10-01 鼠标 5 50
2 103 2023-10-02 键盘 3 150
3 104 2023-10-03 笔记本 1 1000
4 105 2023-10-03 显示器 2 400
************************************************************
Quantity Amount
Product
显示器 2 400
笔记本 3 3000
键盘 3 150
鼠标 5 50
************************************************************
Date
min max
Product
显示器 2023-10-03 2023-10-03
笔记本 2023-10-01 2023-10-03
键盘 2023-10-02 2023-10-02
鼠标 2023-10-01 2023-10-01
5.6.3分组统计练习
import pandas as pd
df = pd.DataFrame({"名称": ["A", "B", "A", "A", "B", "A"],
"颜色": ["红色", "蓝色", "红色", "蓝色", "蓝色", "红色"],
"尺寸": ["大", "大", "小", "小", "大", "大"],
"数量": [10, 20, 15, 30, 10, 20]})
print('df原始数据:')
print(df)
print('*'*30)
# 例1-根据名称分组统计不同颜色的数量总和
print('根据名称分组统计不同颜色的数量总和:')
print(df.groupby(['名称','颜色'])['数量'].sum().reset_index())
print('*'*30)
# 例2-根据名称分组,统计不同颜色的数量平均值
print('根据名称分组,统计不同颜色的数量平均值:')
print(df.loc[:, ['名称', '颜色', '数量']].groupby(['名称','颜色']).mean().reset_index())
print('*'*30)
# 例3-根据名称分组,统计不同颜色和尺寸的数量总和
print('根据名称分组,统计不同颜色和尺寸的数量总和:')
print(df.loc[:, ['名称', '颜色', '尺寸', '数量']].groupby(['名称', '颜色', '尺寸']).sum().reset_index())
运行结果
df原始数据:
名称 颜色 尺寸 数量
0 A 红色 大 10
1 B 蓝色 大 20
2 A 红色 小 15
3 A 蓝色 小 30
4 B 蓝色 大 10
5 A 红色 大 20
******************************
根据名称分组统计不同颜色的数量总和:
名称 颜色 数量
0 A 红色 45
1 A 蓝色 30
2 B 蓝色 30
******************************
根据名称分组,统计不同颜色的数量平均值:
名称 颜色 数量
0 A 红色 15.0
1 A 蓝色 30.0
2 B 蓝色 15.0
******************************
根据名称分组,统计不同颜色和尺寸的数量总和:
名称 颜色 尺寸 数量
0 A 红色 大 30
1 A 红色 小 15
2 A 蓝色 小 30
3 B 蓝色 大 30
5.7透视表pivot_table()
import pandas as pd
#一、
df = pd.DataFrame({'sex': list('FFMFMMF'),
'smoker': list('YNYYNYY'),
'age': [21, 30, 17, 37, 40, 18, 26],
'weight': [120, 100, 132, 140, 94, 89, 123]})
print('df原始数据:')
print(df)
print('*' * 40)
print('看成以smoker分组,对age和weight做mean聚合:')
print(df.pivot_table(values=['age', 'weight'], index='smoker', aggfunc='mean'))
print('*' * 40)
print('对不同的列用不同的聚合:')
print(df.pivot_table(values=['age', 'weight'], index='smoker', aggfunc={'age': 'mean', 'weight': 'median'}))
print('*' * 40)
#二、
data = {'订单日期': pd.date_range(start='2023-01-01', periods=12, freq='M'),
'产品类别': ['电子产品', '家居用品', '服装', '电子产品', '家居用品', '服装', '电子产品', '家居用品', '服装','电子产品', '家居用品', '服装'],
'销售额': [5000, 3000, 2000, 5500, 3200, 2200, 6000, 3500, 2300, 5200, 3100, 2100]
}
df = pd.DataFrame(data)
print('df原始数据:')
print(df)
print('*' * 40)
print('以订单日期为行索引,产品类别为列索引,值为销售额,空值用0填充:')
print(pd.pivot_table(df,values='销售额',columns='产品类别',index='订单日期',fill_value=0))
运行结果:
df原始数据:
sex smoker age weight
0 F Y 21 120
1 F N 30 100
2 M Y 17 132
3 F Y 37 140
4 M N 40 94
5 M Y 18 89
6 F Y 26 123
****************************************
看成以smoker分组,对age和weight做mean聚合:
age weight
smoker
N 35.0 97.0
Y 23.8 120.8
****************************************
对不同的列用不同的聚合:
age weight
smoker
N 35.0 97.0
Y 23.8 123.0
****************************************
df原始数据:
订单日期 产品类别 销售额
0 2023-01-31 电子产品 5000
1 2023-02-28 家居用品 3000
2 2023-03-31 服装 2000
3 2023-04-30 电子产品 5500
4 2023-05-31 家居用品 3200
5 2023-06-30 服装 2200
6 2023-07-31 电子产品 6000
7 2023-08-31 家居用品 3500
8 2023-09-30 服装 2300
9 2023-10-31 电子产品 5200
10 2023-11-30 家居用品 3100
11 2023-12-31 服装 2100
****************************************
以订单日期为行索引,产品类别为列索引,值为销售额,空值用0填充:
产品类别 家居用品 服装 电子产品
订单日期
2023-01-31 0.0 0.0 5000.0
2023-02-28 3000.0 0.0 0.0
2023-03-31 0.0 2000.0 0.0
2023-04-30 0.0 0.0 5500.0
2023-05-31 3200.0 0.0 0.0
2023-06-30 0.0 2200.0 0.0
2023-07-31 0.0 0.0 6000.0
2023-08-31 3500.0 0.0 0.0
2023-09-30 0.0 2300.0 0.0
2023-10-31 0.0 0.0 5200.0
2023-11-30 3100.0 0.0 0.0
2023-12-31 0.0 2100.0 0.0
后续持续学习更新