用于搜索的 Pandas 列索引?
Posted
技术标签:
【中文标题】用于搜索的 Pandas 列索引?【英文标题】:Pandas column indexing for searching? 【发布时间】:2017-07-27 05:33:20 【问题描述】:在关系数据库中,我们可以在列上创建索引以加快对这些列的查询和连接。我想在熊猫数据框上做同样的事情。行索引似乎不是关系数据库提供的。
问题是:默认情况下,pandas 中的列是否为搜索编制索引?
如果没有,是否可以手动索引列以及如何做?
编辑:我已经阅读了 pandas 文档并到处搜索,但没有人提到 pandas 的索引和搜索/合并性能。似乎没有人关心这个问题,尽管它在关系数据库中很重要。任何人都可以就 pandas 的索引和性能发表声明吗?
谢谢。
【问题讨论】:
并非如此,pandas 模型不是内存中关系数据库的模型。您可以查看文档中的“索引”和“多索引”以查看您的选项,但从根本上说,pandas 不是具有“声明性数据导航”功能的 RDBMS。 这是否意味着 Pandas 以“索引”和“多索引”的形式提供列索引?我已阅读文档,但仍不清楚。您能否举例说明如何使用“索引”和“多索引”加速查询/加入? 在 pandas 中,您可以将任何列或列组合声明为索引(或多索引)。这对于搜索或合并都不是必需的。按索引排序并不比按常规列排序快。 (只是通过实验检查。) 这不是必需的,但索引将使搜索/合并比在关系数据库上更快。 我说的是“在熊猫中”。 【参考方案1】:正如@pvg 所提到的——pandas 模型不是内存关系数据库的模型。所以,如果我们试图用 sql 来类比 pandas 并没有多大帮助,而且它的特性。相反,让我们从根本上看问题 - 您正在有效地尝试加速列查找/连接。
您可以通过将您希望连接的列设置为两个数据框(您希望连接的左右数据框)中的索引来大大加快连接速度,并且然后对两个索引进行排序。
这是一个示例,向您展示加入排序索引时可以获得的加速:
import pandas as pd
from numpy.random import randint
# Creating DATAFRAME #1
columns1 = ['column_1', 'column_2']
rows_df_1 = []
# generate 500 rows
# each element is a number between 0 and 100
for i in range(0,500):
row = [randint(0,100) for x in range(0, 2)]
rows_df_1.append(row)
df1 = pd.DataFrame(rows_df_1)
df1.columns = columns1
print(df1.head())
第一个数据框如下所示:
Out[]:
column_1 column_2
0 83 66
1 91 12
2 49 0
3 26 75
4 84 60
让我们创建第二个数据框:
columns2 = ['column_3', 'column_4']
rows_df_2 = []
# generate 500 rows
# each element is a number between 0 and 100
for i in range(0,500):
row = [randint(0,100) for x in range(0, 2)]
rows_df_2.append(row)
df2 = pd.DataFrame(rows_df_1)
df2.columns = columns2
第二个数据框如下所示:
Out[]:
column_3 column_4
0 19 26
1 78 44
2 44 43
3 95 47
4 48 59
现在假设您希望在 column_1 == column_3
上加入这两个数据帧
# setting the join columns as indexes for each dataframe
df1 = df1.set_index('column_1')
df2 = df2.set_index('column_3')
# joining
%time
df1.join(df2)
Out[]:
CPU times: user 4 ms, sys: 0 ns, total: 4 ms
Wall time: 46 ms
如您所见,只需将连接列设置为数据帧索引并在之后连接 - 大约需要 46 毫秒。现在,让我们在对索引进行排序后尝试加入 *
# sorting indexes
df1 = df1.sort_index()
df2 = df2.sort_index()
Out[]:
CPU times: user 0 ns, sys: 0 ns, total: 0 ns
Wall time: 9.78 µs
这需要大约 9.78 µs,快得多。
我相信您可以将相同的排序技术应用于 pandas 列 - 按字典顺序对列进行排序并修改数据框。我还没有测试过下面的代码,但是这样的代码应该可以加快列查找速度:
import numpy as np
# Lets assume df is a dataframe with thousands of columns
df = read_csv('csv_file.csv')
columns = np.sort(df.columns)
df = df[columns]
现在列查找应该快得多 - 如果有人可以在包含一千列的数据帧上进行测试,那就太好了
【讨论】:
感谢您的解释。在我的计算机上,未排序和排序索引分别花费了 33 us 和 11 us,这比在您的计算机上要少得多。其实我对熊猫性能调优这个话题还是很困惑。好像没有什么好的文档。以上是关于用于搜索的 Pandas 列索引?的主要内容,如果未能解决你的问题,请参考以下文章
pandas读取csv数据index_col参数指定作为行索引的数据列索引列表形成复合(多层)行索引使用方括号[]基于列索引名称元组索引列数据(index tuple)
pandas读取csv数据index_col参数指定作为行索引的数据列索引列表形成复合(多层)行索引使用方括号[]基于列索引元组列表索引多列数据(index tuple list)
pandas读取csv数据header参数指定作为列索引的行索引列表形成复合(多层)列索引使用set_index函数把数据列转化为行索引(keys参数指定需要被转化的层列索引)
pandas读取csv数据header参数指定作为列索引的行索引列表形成复合(多层)列索引使用set_index函数把数据列转化为行索引(keys参数指定需要被转化的层列索引)
pandas读取csv数据header参数指定作为列索引的行索引列表形成复合(多层)列索引使用iloc基于行索引位置列表筛选dataframe数据中指定位置的多个数据行