一、写在开头
最近在做一个机器学习的项目,发现有很多地方用到pandas,很多东西用起来总觉得别扭,比如我想在某张表后面插一列数据,又比如我想找到两张表相等的某个值所在行或者所在列,将某一行、某一列数据删除,将某一行、某一列数据替换,表头有两个的怎么删除一个,有一个表头的怎么扩展成两个表头、怎么对数据索引,等等问题。我发现这里面内容繁杂,经常出现用这个,忘记那个,而这些东西有必须得会,所以我想总结一下,方便以后自己复习,同时也为社区做一份贡献,毕竟有人点赞是一件很开心的事情。
二、如何将pandas这些方法分门别类
有时候我对pandas的方法用起来的感觉:乱,我在想有没有一种好的方法,在理解pandas时能够不这么乱,其实很多时候,我们使用pandas的时候是从excel或者数据导入原始数据的,提到数据库,我们首先想到的是:创增删改查!!! 我们是不是也可以通过这种方法来总结pandas呢?当然可以,这样总结下来,就把学习pandas的框架搭建起来,接下来需要做的就是不断往这个框架填充细节,争做大厦就建立起来了。我们先来介绍一下pandas的数据结构:
DataFrame 和 Series 是 Pandas 库中两种主要的数据结构,用于存储和处理数据。它们之间的主要区别如下:
- Series:
- 一维数组,类似于 Python 列表,但可以包含任何数据类型(整数、浮点数、字符串、Python 对象等)。
- 每个元素都有一个索引,可以是整数或自定义标签。
- 通常用于处理一维数据。
- DataFrame:
- 二维表格型数据结构,类似于 Excel 表格或 SQL 表。
- 由行和列组成,每列可以是不同的数据类型。
- 每列都有一个标签(列名),每行也有一个可选的标签(行名)。
- 通常用于处理多维数据,并提供更丰富的数据操作和分析功能。
以下是它们之间的一些主要差异:
- 维度:Series 是一维的,而 DataFrame 是二维的。
- 数据类型:Series 可以包含任何数据类型,而 DataFrame 每列可以是不同的数据类型。
- 索引:Series 和 DataFrame 都有索引,但 DataFrame 的索引包括行索引和列索引。
- 操作:DataFrame 提供了更多的数据操作和分析功能,如分组、透视表、合并等。
三、创建pandas数据
这里列出的只是简单的方法,这些方法有很多重载,里面的参数没法全部举例,得去pandas的官网查看每个参数的意义。链接如下:
Input/output — pandas 2.1.3 documentation (pydata.org)
1、创建空数据
import pandas as pd
df = pd.DataFrame()
print(df)
2、从字典创建 DataFrame
import pandas as pd
data = {'Name': ['Tom', 'Nick', 'John', 'Julia'], 'Age': [20, 21, 19, 18]}
df = pd.DataFrame(data)
print(df)
3、从列表创建 DataFrame:
import pandas as pd
data = [['Tom', 20], ['Nick', 21], ['John', 19], ['Julia', 18]]
df = pd.DataFrame(data, columns=['Name', 'Age'])
print(df)
4、从 CSV 文件创建 DataFrame:
import pandas as pd
df = pd.read_csv('filename.csv') # 将 'filename.csv' 替换为你的 CSV 文件路径
print(df)
5、从 Excel 文件创建 DataFrame:
import pandas as pd
df = pd.read_excel('filename.xlsx') # 将 'filename.xlsx' 替换为你的 Excel 文件路径
print(df)
6、从 SQL 数据库创建 DataFrame:
首先,你需要安装 sqlalchemy
和 pandas
库。然后,你可以使用以下代码从 SQL 数据库创建 DataFrame:
from sqlalchemy import create_engine
import pandas as pd
engine = create_engine('sqlite:///your_database.db') # 将 'your_database.db' 替换为你的数据库路径
query = "SELECT * FROM your_table" # 将 'your_table' 替换为你的表名
df = pd.read_sql_query(query, engine)
print(df)
7、从numpy中创建 DataFrame:
import pandas as pd
df = pd.DataFrame(np.arange(16).reshape(4, 4), columns=['A', 'B', 'C', 'D'])
df
四、增加数据
1、增加单行
使用 _append()
方法添加行:
append()
方法用于将一行或多行追加到 DataFrame 的末尾。
import pandas as pd
# 创建一个示例 DataFrame
df = pd.DataFrame({
'A': [1, 2, 3],
'B': [4, 5, 6]
})
# 创建要追加的新行
new_row = pd.Series([7, 8], index=['A', 'B'])
# 使用 append() 方法添加新行
df = df.append(new_row, ignore_index=True)
print(df)
使用 loc[]
或 iloc[]
添加行:
你可以使用 loc[]
或 iloc[]
选择 DataFrame 的特定位置,并将新数据分配给这些位置。这种方法适用于在 DataFrame 的特定位置插入新行。
import pandas as pd
# 创建一个示例 DataFrame
df = pd.DataFrame({
'A': [1, 2, 3],
'B': [4, 5, 6]
})
# 使用 loc[] 添加新行
df.loc[3] = [7, 8]
print(df)
2、增加单列
使用 insert()
方法添加列:
insert()
方法用于在 DataFrame 的指定位置插入新列。你需要指定新列的位置、列名和新列的值。
import pandas as pd
# 创建一个示例 DataFrame
df = pd.DataFrame({
'A': [1, 2, 3],
'B': [4, 5, 6]
})
# 创建要插入的新列数据
new_col = pd.Series([7, 8, 9])
# 使用 insert() 方法添加新列,位置为 1,列名为 'C'
df.insert(loc=1, column='C', value=new_col)
print(df)
使用 assign()
方法添加列:
assign()
方法是一种更简洁的方式,可以在不改变原始 DataFrame 的情况下添加新列。这对于创建新的 DataFrame 版本非常有用。
import pandas as pd
# 创建一个示例 DataFrame
df = pd.DataFrame({
'A': [1, 2, 3],
'B': [4, 5, 6]
})
# 使用 assign() 方法添加新列,列名为 'C'
df = df.assign(C=[7, 8, 9])
print(df)
3、表合并
concat()
方法:
concat()
方法用于沿着一条轴(行或列)将多个 DataFrame 连接在一起。默认情况下,concat()
沿着行轴(axis=0)连接 DataFrame。
import pandas as pd
# 创建两个示例 DataFrame
df1 = pd.DataFrame({'A': [1, 2], 'B': [3, 4]})
df2 = pd.DataFrame({'A': [5, 6], 'B': [7, 8]})
# 使用 concat() 方法合并 DataFrame
result = pd.concat([df1, df2], ignore_index=True)
print(result)
merge()
方法:
merge()
方法类似于 SQL 中的 JOIN 操作,用于根据两个 DataFrame 中的键将它们合并在一起。你可以选择不同的合并类型,如内连接、左连接、右连接和外连接。
import pandas as pd
# 创建两个示例 DataFrame
df1 = pd.DataFrame({'key': ['A', 'B'], 'value': [1, 2]})
df2 = pd.DataFrame({'key': ['A', 'B'], 'value': [3, 4]})
# 使用 merge() 方法合并 DataFrame,默认为内连接
result = pd.merge(df1, df2, on='key')
print(result)
join()
方法:
join()
方法是 DataFrame 的一个成员方法,用于将另一个 DataFrame 或 Series 对象合并到原始 DataFrame 中。默认情况下,join()
根据索引进行合并。如果需要根据列进行合并,可以设置参数 on
。
import pandas as pd
df1 = pd.DataFrame({'A': [30, 7, 8, 9], 'B': [1.2, 2.4, 4.5, 7.3], 'C': ["aa", "bb", "cc", "dd"]})
df2 = pd.DataFrame({'D': [1, 2]})
df1.join(df2)
五、删除数据
1、使用 drop()
方法:
drop()
方法可以用于删除 DataFrame 中的行或列。你可以指定要删除的行标签或列标签,以及删除的方式(按行还是按列)。默认情况下,drop()
方法会返回一个新的 DataFrame,而不会修改原始 DataFrame。如果要直接修改原始 DataFrame,可以设置参数 inplace=True
。
import pandas as pd
# 创建一个示例 DataFrame
df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})
# 使用 drop() 方法删除指定的行
df_dropped = df.drop([0]) # 删除第一行,返回新的 DataFrame
# 使用 drop() 方法删除指定的列
df_dropped = df.drop(['B'], axis=1) # 删除 'B' 列,返回新的 DataFrame
# 直接修改原始 DataFrame
df.drop([1], inplace=True) # 删除第二行,直接修改原始 DataFrame
2、使用布尔索引:
通过使用布尔索引,你可以选择要保留的行或列,从而间接地删除不需要的数据。通过对 DataFrame 的列进行操作,得到一个布尔值的 Series,然后使用该 Series 来选择满足条件的行。不满足条件的行将被排除。
import pandas as pd
# 创建一个示例 DataFrame
df = pd.DataFrame({'A': [1, 2, 3, 4], 'B': [5, 6, 7, 8]})
# 使用布尔索引选择满足条件的行,不满足条件的行将被排除
df_filtered = df[df['A'] > 2] # 选择 'A' 列大于 2 的行,返回新的 DataFrame
3、使用 pop()
方法:
pop()
方法可以用于删除 DataFrame 中的列,并返回被删除的列作为 Series 对象。你可以指定要删除的列标签。与 drop()
方法不同,pop()
方法会直接修改原始 DataFrame。需要注意的是,删除操作可能会改变 DataFrame 的索引。如果删除了某些行或列,后续的操作可能会受到影响。因此,在进行删除操作之前,最好先备份原始数据或创建数据的副本。
import pandas as pd
# 创建一个示例 DataFrame
df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})
# 使用 pop() 方法删除指定的列,并返回被删除的列
deleted_column = df.pop('B') # 删除 'B' 列,返回被删除的列作为 Series 对象
六、修改数据
在 Pandas 中,可以使用多种方法修改 DataFrame 中的数据。以下是一些常用的方法:
1、直接赋值:
最简单的方法是直接对 DataFrame 的元素进行赋值。通过指定行标签和列标签,你可以直接修改 DataFrame 中的单个元素或整列数据。
import pandas as pd
# 创建一个示例 DataFrame
df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})
# 修改单个元素的值
df.loc[0, 'A'] = 10
# 修改整列数据的值
df['B'] = [7, 8, 9]
print(df)
2、使用 replace()
方法:
replace()
方法可以用于替换 DataFrame 中的特定值。你可以指定要替换的值和替换后的新值。
import pandas as pd
# 创建一个示例 DataFrame
df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})
# 使用 replace() 方法替换特定值
df.replace(2, 10, inplace=True) //将表中的2全部替换成10
print(df)
3、使用 apply()
方法:
apply()
方法可以应用于整列或整行的数据,并对每个元素执行指定的函数。你可以定义一个函数,该函数接受一个元素作为输入,并返回修改后的值。然后,使用 apply()
方法将该函数应用于 DataFrame 的列或行。
import pandas as pd
# 创建一个示例 DataFrame
df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})
# 定义一个函数,将每个元素乘以 2
def multiply_by_2(x):
return x * x
# 使用 apply() 方法将函数应用于整列数据
df['A'] = df['A'].apply(multiply_by_2)
print(df)
4、使用 map()
方法:
map()
方法可以应用于 Series 对象(DataFrame 的列),并对每个元素执行指定的函数。与 apply()
方法类似,你可以定义一个函数,并将其应用于 Series 对象的每个元素。
import pandas as pd
# 创建一个示例 DataFrame
df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})
# 定义一个字典,将特定值映射到新值
mapping_dict = {1: 10, 2: 20}
# 使用 map() 方法将字典映射应用于整列数据
df['A'] = df['A'].map(mapping_dict)
print(df)
七、查找数据
在 Pandas 中,可以使用多种方法来查找数据。以下是一些常用的方法:
1、使用布尔索引:
通过比较操作符(如等于、大于、小于等)对 DataFrame 的列进行操作,得到一个布尔值的 Series。然后,这个 Series 可以用于从 DataFrame 中选择满足条件的行。
import pandas as pd
# 创建一个示例 DataFrame
df = pd.DataFrame({'A': [1, 2, 3, 4], 'B': [5, 6, 7, 8]})
# 使用布尔索引查找满足条件的行
result = df[df['A'] > 2] //找到第A列中大于2的元素所在行
print(result)
2、使用 loc[]
和 iloc[]
:
loc[]
是基于标签的索引工具,它接受行标签和列标签作为参数,并返回对应位置的数据。iloc[]
是基于位置的索引工具,它接受行号和列号作为参数,并返回对应位置的数据。
import pandas as pd
# 创建一个示例 DataFrame
df = pd.DataFrame({'A': [1, 2, 3, 4], 'B': [5, 6, 7, 8]}, index=['x', 'y', 'z', 'w'])
# 使用 loc[] 查找特定行标签和列标签的值
result = df.loc['y', 'B'] //查找行标签为y,列标签为B的值
print(result)
# 使用 iloc[] 查找特定位置的值
result = df.iloc[2, 1] //查找第2行第1列的值
print(result)
3、使用 isin()
方法:
isin()
方法用于检查 DataFrame 的列中是否包含指定的值或值的列表,返回一个布尔值的 DataFrame。然后,可以使用布尔索引来选择满足条件的行。
import pandas as pd
# 创建一个示例 DataFrame
df = pd.DataFrame({'A': [1, 2, 3, 4], 'B': [5, 6, 7, 8]})
# 使用 isin() 方法查找特定值是否存在
result = df[df['A'].isin([1, 3])]
print(result)
4、使用 query()
方法:
query()
方法允许你使用字符串表达式来查询 DataFrame,并返回满足条件的行。这是一种更直观和灵活的方式来查找数据。
import pandas as pd
# 创建一个示例 DataFrame
df = pd.DataFrame({'A': [1, 2, 3, 4], 'B': [5, 6, 7, 8]})
# 使用 query() 方法查找满足条件的行
result = df.query('A > 2 and B < 8')
print(result)
5、找出每列的最小值的索引。
import pandas as pd
df = pd.DataFrame(np.arange(16).reshape(4, 4), columns=['A', 'B', 'C', 'D'])
df.idxmin(axis=0) #等价 df.idxmin()
6、找出每行的最小值的索引
import pandas as pd
df = pd.DataFrame(np.arange(16).reshape(4, 4), columns=['A', 'B', 'C', 'D'])
df.idxmin(axis=1)