看过来
《pandas 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gairuo123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
数据分析过程中,对数据的修改调整也是比较多的,最简单的如学生成绩表加一列把总分算出来。根据某一列的数据解析出指定内容,如学生成绩单有个学生家庭地址,然后把所在小区解析出来形成新的一列。
注:本文所使用的 df
和 s
是数据信息一文中的数据。
Pandas 的数据修改是进行赋值,先把要修改的数据筛选出来,然后将同结构或者可解包的数据赋值给它:
df.Q1 = [1, 3, 5, 7, 9] * 20 # 就会把值进行修改
df.loc[1:3, 'Q1':'Q2'] = 99 # 这个范围的数据会全变成 99
df.loc[df.name=='Arry', 'Q1':'Q4'] = [66,77,88,99] # 指定多列
df.loc[df.name.isin(['Arry', 'Ack']), 'Q1'] = (33, 44) # 修改列值
对索引的修改包含行索引和列索引:
# 对索引值进行修改
df.rename(columns={"Q1": "a", "Q2": "b"}) # 对表头进行修改
df.rename(index={0: "x", 1: "y", 2: "z"}) # 对索引进行修改
df.rename(index=str) # 对类型进行修改
df.rename(str.lower, axis='columns') # 传索引类型
df.rename({1: 2, 2: 4}, axis='index')
# 对索引名进行修改
s.rename_axis("animal")
df.rename_axis("animal") # 默认是列索引
df.rename_axis("limbs", axis="columns") # 指定行索引
# 多层索引时可以将type修改为class
df.rename_axis(index={'type': 'class'})
# 可以用 set_axis 进行设置修改
s.set_axis(['a', 'b', 'c'], axis=0)
df.set_axis(['I', 'II'], axis='columns')
df.set_axis(['i', 'ii'], axis='columns', inplace=True)
替换数据:
s.replace(0, 5) # 将列数据中 0 换为 5
df.replace(0, 5) # 将数据中所有 0 换为 5
df.replace([0, 1, 2, 3], 4) # 将 0-3 全换成 4
df.replace([0, 1, 2, 3], [4, 3, 2, 1]) # 对应修改
# {‘pad’, ‘ffill’, ‘bfill’, None} 试试
s.replace([1, 2], method='bfill') # 向下填充
df.replace({0: 10, 1: 100}) # 字典对应修改
df.replace({'Q1': 0, 'Q2': 5}, 100) # 指定字段的指定值修改为 100
df.replace({'Q1': {0: 100, 4: 400}}) # 指定列里指定值按指定的值替换
# 使用正则
df.replace(to_replace=r'^ba.$', value='new', regex=True)
df.replace({'A': r'^ba.$'}, {'A': 'new'}, regex=True)
df.replace(regex={r'^ba.$': 'new', 'foo': 'xyz'})
df.replace(regex=[r'^ba.$', 'foo'], value='new')
删除空值:
df.dropna() # 一行中有一个空NaT就删除
df.dropna(axis='columns') # 只保留全有值的列
df.dropna(how='all') # 行或列全没值才删除
df.dropna(thresh=2) # 至少有两个空值时才删除
df.dropna(inplace=True) # 删除并生效替换
填充空值:
df.fillna(0) # 空全修改为 0
# {‘backfill’, ‘bfill’, ‘pad’, ‘ffill’, None}, default None
df.fillna(method='ffill') # 都修改为它前一个值
values = {'A': 0, 'B': 1, 'C': 2, 'D': 3}
df.fillna(value=values) # 各列替换空值不同
df.fillna(value=values, limit=1) # 只替换第一个
更多内容可参考数据清洗章节。
Pandas 的数据添加修改非常简单,新赋值一个原 DF 中没有列名就会产生一个新列:
df['foo'] = 100 # 增加一列 foo, 所有值都是 100
df['foo'] = df.Q1 + df.Q2 # 新列为两列相加
df['foo'] = df['Q1'] + df['Q2'] # 同上
# 把所有为数字的加起来
df['total'] = df.select_dtypes(include=['int']).sum(1)
df['total'] = df.loc[:,'Q1':'Q4'].apply(lambda x: sum(x), axis='columns')
df.loc[:, 'Q10'] = '我是新来的' # 也可以
# 增加一列并赋值,不满足条件的为 NaN
df.loc[df.num >= 60, '成绩'] = '合格'
df.loc[df.num < 60, '成绩'] = '不合格'
使用df.assign()
指定新列:
df.assign(Q5=[100]*100) # 新增加一列 Q5
df = df.assign(Q5=[100]*100) # 赋值生效
df.assign(Q6=df.Q2/df.Q1) # 计算并增加 Q6
df.assign(Q7=lambda x: x.Q1 * 9 / 5 + 32) # 使用 lambda
# 添加一列,值为表达式结果 True or False
df.assign(tag=df.Q1>df.Q2)
# True 为1 False 为 0
df.assign(tag=(df.Q1>df.Q2).astype(int))
# 映射文案
df.assign(tag=(df.Q1>60).map({True:'及格',False:'不及格'}))
# 增加多个
df.assign(Q8=lambda x: x.Q1*5,
Q9=lambda x: x.Q8+1) # 注 Q8没生效不能直接 df.Q8
关于 assign() 指定新列的方法,可以访问 assign() 查看更多的介绍。
使用 df.insert()
插入新的行,会立即生效:
# 一般格式 df.insert(新列索引位, 名字, 数据)
df.insert(len(df.columns), 'Qx',
pd.Series(np.random.randn(100), index=df.index))
df.eval()
可以进行赋值定义一个新列:
df['C1'] = df.eval('Q2 + Q3')
df.eval('C2 = Q2 + Q3') # 计算
a = df.Q1.mean()
df.eval("C3 = `Q3`+@a") # 使用变量
df.eval("C3 = Q2 > (`Q3`+@a)") # 加一个布尔值
df.eval('C4 = name + team', inplace=True) # 立即生效
更多 eval 细节,可以浏览关于 df.eval() 的详细介绍。
最简单的办法利用新索引,按位置给出新数据的列表:
df.loc[101] = ['tom', 'A', 88, 88, 88, 88]
df.loc[101]={'Q1':88,'Q2':99} # 指定列,无数据列值为NaN
df.loc[df.shape[0]+1] = {'Q1':88,'Q2':99} # 自动增加索引
df.loc[len(df)+1] = {'Q1':88,'Q2':99}
如果需要批量操作,可以使用迭代的办法。
rows = [[1,2],[3,4],[5,6]]
for row in rows:
df.loc[len(df)] = row
df.append()
可以追加一个新行。
df = pd.DataFrame([[1, 2], [3, 4]], columns=list('AB'))
df2 = pd.DataFrame([[5, 6], [7, 8]], columns=list('AB'))
df.append(df2)
pd.concat([s1, s2])
可以将两个 df/s 连接起来:
s1 = pd.Series(['a', 'b'])
s2 = pd.Series(['c', 'd'])
pd.concat([s1, s2])
pd.concat([s1, s2], ignore_index=True) # 索引重新编
# 原数索引不就,增加一个一层索引(keys 里的内容)变成多层索引
pd.concat([s1, s2], keys=['s1', 's2'])
pd.concat([s1, s2], keys=['s1', 's2'],
names=['Series name', 'Row ID'])
# df 同样道理
pd.concat([df1, df2])
pd.concat([df1, df3], sort=False)
pd.concat([df1, df3], join="inner") # 只连相同列
pd.concat([df1, df4], axis=1) # 连接列
关于将多个数据合并连接的操作可以查看教程数据合并。
pop() 方法用于删除列:
df.pop('Q1') # 删除一列
s.pop(3) # 删除一个索引位
# 也可以把想要的列筛选出来赋值给 df 达到删除的目的
df.update() 可以对同位置,即同索引上的数据进行就地替换,实现了修改的作用。详见可见 df.update()。
df = pd.DataFrame({'A': [1, 2, 3],
'B': [4, 5, 6]},
index=['x', 'y', 'z']
)
df
'''
A B
x 1 4
y 2 5
z 3 6
'''
# 修改 (y, B) 位置的原值5修改为 99
df.update(pd.Series([99], index=['y'], name='B'))
df
'''
A B
x 1 4.0
y 2 99.0
z 3 6.0
'''
更新时间:2024-08-07 18:05:09 标签:pandas 修改