所以我有一个巨大的数据框,我需要迭代地分割一些不同的列。 所有要切片的列,我都在列表中,例如
[col1, col2, col3]
[col2, col3, col4]
[col1, col2, col4]
等等等
我现在要做的是循环浏览列列表,然后使用loc选择所有列,例如
df.loc[:,columns]
(其中列是上述列表的一行,例如[col1, col2, col3]
)
这可行,但是就像我提到的,我有一个巨大的数据框,并且列的列表比3大得多。
有什么方法可以向量化此操作并立即完成所有操作,同时仍然获得不同的单独结果?我不希望有1个数据框,但希望每个单独的列组合都具有不同的数据框切片。
编辑:
这是我现在使用的示例,并且有效:
import pandas as pd
import numpy as np
data = {'Col1':['Tom', 'nick', 'krish', 'jack'], 'Col2':[20, 21, 19, 18], 'Col3':[20, 21, 19, 18], 'Col4':[20, 21, 19, 18]}
# Create DataFrame
df = pd.DataFrame(data)
cols_to_select = np.empty(3, dtype=np.object)
cols_to_select[0] = ['Col1', 'Col3']
cols_to_select[1] = ['Col2', 'Col3']
cols_to_select[2] = ['Col3', 'Col4']
for col in cols_to_select:
print(df.loc[:, col])
输出:
Col1 Col3
0 Tom 20
1 nick 21
2 krish 19
3 jack 18
Col2 Col3
0 20 20
1 21 21
2 19 19
3 18 18
Col3 Col4
0 20 20
1 21 21
2 19 19
3 18 18
问题是,在此示例中,在for循环中,列的切片发生了3次。可以提高效率-保持相同的结果吗?
答案 0 :(得分:1)
可能不值得一个答案,而只是一个评论,但是:在这种情况下,您可能考虑得太多了-在任何情况下,简单的列表理解就足够了……
In [1]: from pandas import util
In [10]: util.testing.K = 20
In [11]: df = util.testing.makeDataFrame()
In [13]: %timeit df[['A', 'G', 'M', 'N']]
289 µs ± 7.24 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
所以您可以简单地做类似的事情
df_list = [df[cols] for cols in col_selectors]
这可能与您可以做到的差不多。
这为什么起作用(以及您要进行哪种矢量化处理):基本上,pandas是numpy系列的列表;每个系列都是一列(这就是为什么列具有数据类型而不是行的原因)。因此,提取列的列表实际上只是获取想要的每列系列的指针的列表-相当便宜的操作。这不同于捕获行的子集-为此,熊猫(通过numpy)必须从系列(数组)中提取一些值并将它们连接成一个新的系列。因此,获取一组行会非常昂贵,而获取列的子集则很便宜。
(请注意,转置操作似乎也很便宜,因此有时转置DataFrame然后提取列比提取各种行集要快很多,但在这里肯定是YMMV:)
编辑:对于更大的示例,这里是10000列,每列10000个条目。它确实花费了更长的时间,但并没有那么明显-我实际上不确定为什么要花费更长的时间,我没想到会这么长,可能是因为从系列列表中生成数据框会受到此影响。
In [3]: df = pd.DataFrame(np.random.rand(10000, 10000))
In [5]: df
Out[5]:
....
[10000 rows x 10000 columns]
In [6]: %timeit df[[2000,3000,4000,5000]]
512 µs ± 13 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
In [7]: %timeit df[[1,4,9,16,25,32,200,300,400]]
968 µs ± 21.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)