在实际开发中,我们需要对DataFrame中包含的实际值执行某些操作,在本章节中将介绍几种格式化DataFrame值的方法。
主要内容包括:
- 替换DataFrame中元素的字符串
- 删除DataFrame中元素的子字符串
- 分割DataFrame中的元素
- DataFrame的元素应用函数
要替换DataFrame中的某些字符串,可以使用replace()
函数,传递想要更改的值,然后是要替换它们的值。
像下面这个示例一样,第一个参数是需要替换的数组,第二个参数是替换的值所对应的新数组。
import numpy as np
import pandas as pd
df = pd.DataFrame(data=np.array([[1, 2, 3], [4, 5, 6], [1, 8, 9]]))
print(df)
# 将数字1, 4, 5, 6分别替换为"chainDesk", "I", "am", "LiXu"。
df.replace([1, 4, 5, 6],
["chainDesk", "I", "am", "LiXu"],
inplace=True)
print(df)
运行后输出如下:
0 1 2
0 1 2 3
1 4 5 6
2 1 8 9
0 1 2
0 chainDesk 2 3
1 I am LiXu
2 chainDesk 8 9
注意:遇到替换的值一样的元素,会一起替换掉,比如上面的数字1都将替换成了"chainDesk"。
另外我们也可以使用字典的形式去替换数据,如:{1:"chainDesk"}
。
删除不需要的字符串是一个比较麻烦的操作,但是幸运的是,在Python中这个问题有一个简单的解决方案!
import numpy as np
import pandas as pd
df = pd.DataFrame(data=np.array([[1, 2, '-aB'],
[4, 5, '+123aB'],
[7, 8, 'b+123b']]),
index=[2.5, 12.6, 4.8],
columns=[48, 49, "result"])
print(df)
# 从result列中的字符串中删除不需要的部分
df['result'] = df['result'].map(lambda x: x.lstrip('+-').rstrip('aAbBcC'))
print(df)
运行后输出:
48 49 result
2.5 1 2 -aB
12.6 4 5 +123aB
4.8 7 8 b+123b
48 49 result
2.5 1 2
12.6 4 5 123
4.8 7 8 b+123
在名称为result
的列上使用lambda函数应用于该列的每个元素。x.lstrip('+-').rstrip('aAbBcC')
这个代码代表:删除左边的+
或者-
字符,也删除右边的aAbBcC
任意字符。
将DataFrame对象中的某许元素,按照指定的字符串,如空格,进行分割为多个元素。这是一个更困难的格式化任务,请按照下面的步骤完成这个功能。
import numpy as np
import pandas as pd
df = pd.DataFrame(data=np.array([[1, 2, 3],
[4, 5, 'I am LiXu'],
[7, 8, 'b+123b']]),
columns=[48, 49, "Ticket"])
print("df:\n", df)
# 1. 拆分第二行中的"I am LiXu"成三个值,生成一个series
ticket_series = df['Ticket'].str.split(' ').apply(pd.Series, 1).stack()
print("\n第一步:ticket_series:\n", ticket_series)
# 2. 删除一列以与DataFrame对应,便于添加
ticket_series.index = ticket_series.index.droplevel(-1)
print("\n第二步:ticket_series:\n", ticket_series)
# 3. 让ticket_series成为DataFrame对象
ticketdf = pd.DataFrame(ticket_series)
print("\n第三步:ticketdf:\n", ticketdf)
# 4. 从df中删除Ticket列
del df['Ticket']
print("\n第四步:df:\n", df)
# 5. 将ticketdf DataFrame加入到df
df = df.join(ticketdf)
print("\n第五步:df:\n", df)
运行之后从结果中我们一步步来进行分析:
第一步:ticket_series = df['Ticket'].str.split(' ').apply(pd.Series, 1).stack()
以’ '空格拆分"Ticket"列数据,然后生成一个series对象,那么原始数据中’I am LiXu’将会被拆分成三个值。ticket_series
输出如下:
第一步:ticket_series:
0 0 3
1 0 I
1 am
2 LiXu
2 0 b+123b
dtype: object
最后个stack()函数是将新对象进行堆叠,否则会有NaN值,如下:
第一步:ticket_series:
0 1 2
0 3 NaN NaN
1 I am LiXu
2 b+123b NaN NaN
第二步:ticket_series.index = ticket_series.index.droplevel(-1)
删除一列无用的数据后以与DataFrame对应,便于添加。输出如下:
第二步:ticket_series:
0 3
1 I
1 am
1 LiXu
2 b+123b
dtype: object
第三步:ticketdf = pd.DataFrame(ticket_series)
让ticket_series成为DataFrame对象,以使可以将其添加到初始的DataFrame df中,输出:
第三步:ticketdf:
0
0 3
1 I
1 am
1 LiXu
2 b+123b
第四步:del df['Ticket']
为避免DataFrame中出现任何重复项,从df中删除了Ticket
列,输出:
第四步:df:
48 49
0 1 2
1 4 5
2 7 8
第五步:df = df.join(ticketdf)
将ticketdf DataFrame加入到df DataFrame中,输出:
第五步:df:
48 49 0
0 1 2 3
1 4 5 I
1 4 5 am
1 4 5 LiXu
2 7 8 b+123b
第一步:
我们可以对DataFrame中的数据调用函数来设置数据,下面我们先来定义一个lambda函数:
doubler = lambda x: x*2
完整的代码如下:
import numpy as np
import pandas as pd
df = pd.DataFrame(data=np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]),
columns=['A', 'B', 'C'])
print(df)
doubler = lambda x: x*2
# 在df的'B'这列应用doubler函数
df2 = df['B'].apply(doubler)
print("\ndf2:\n", df2)
运行后输出:
A B C
0 1 2 3
1 4 5 6
2 7 8 9
df2:
0 4
1 10
2 16
Name: B, dtype: int64
您可以使用.loc[]
或.iloc[]
选择一行或者直接对df所有元素应用doubler函数。
然后,您将执行类似这样的操作,具体取决于您是要根据其位置还是根据其标签选择索引:
df.loc[0].apply(doubler)
第二步:
如果想要将此doubler函数不仅应用于DataFrame B
的列,还应用每个元素,则可以使用applymap()
将doubler
函数应用于整个DataFrame中的每个元素,紧接着上面的代码,在最后加上如下两行代码
df3 = df.applymap(doubler)
print("\ndf3:\n", df3)
运行后输出
df3:
A B C
0 2 4 6
1 8 10 12
2 14 16 18
第三步:
上面的两个示例,应用函数的是在运行时创建的lambda函数或匿名函数。但是,我们也可以编写自己的函数。例如:
import numpy as np
import pandas as pd
df = pd.DataFrame(data=np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]),
columns=['A', 'B', 'C'])
print(df)
def doubler(x):
if x % 2 == 0:
return x
else:
return x * 2
# 使用applymap()将doubler()应用于DataFrame对象
doubled_df = df.applymap(doubler)
print(doubled_df)
运行后输出:
A B C
0 1 2 3
1 4 5 6
2 7 8 9
A B C
0 2 2 6
1 4 10 6
2 14 8 18
若有疑问,欢迎联系作者(微信:lixu1770105)。