繁体   English   中英

从数据框的列切片中获取numpy值的最快方法是什么

[英]What is the fastest way to get the numpy values from a column slice of a dataframe

我经常尝试决定如何获取与pandas数据框中的几个(但不是全部)列关联的numpy数组。

所以我想问,最有效的方法是获取与数据框中的几列而不是所有列关联的值的数组?

df = pd.DataFrame(np.arange(10).reshape(-1, 5), columns=list('ABCDE'))
print(df)

   A  B  C  D  E
0  0  1  2  3  4
1  5  6  7  8  9

什么是最快的获取方式

df[['B', 'D']].values

array([[1, 3],
       [6, 8]])

我想到了这些方法...我欢迎在分析中加​​入更多方法

结论
对于少数列,似乎找到列位置并用整数切片非常有效。 但是对于大型数组和大量列, as_matrix非常好(如预期)。

from timeit import timeit
import pandas as pd
import numpy as np
from string import ascii_uppercase as up


def slc_df_2val(df, cols):
    return df[cols].values

def as_matrix(df, cols):
    return df.as_matrix(cols)

def hstack_per_col(df, cols):
    return np.hstack([df[c].values[:, None] for c in cols])

def stack_per_col_T(df, cols):
    return np.stack([df[c].values for c in cols]).reshape(-1, len(cols))

def get_loc_slc_array(df, cols):
    a = [df.columns.get_loc(c) for c in cols]
    return df.values[:, a]

然后我进行以下测试

mcol = pd.MultiIndex.from_product([list(up[:10]), list(up[-10:])])

sizes = pd.MultiIndex.from_product(
    [[10, 100, 1000, 10000], [1, 5, 10, 20, 30, 40]],
    names=['n', 'm'])

methods = pd.Index(
    'slc_df_2val as_matrix hstack_per_col stack_per_col_T get_loc_slc_array'.split(),
    name='method')

results = pd.DataFrame(index=sizes, columns=methods)

np.random.seed([3,1415])
for n in sizes.levels[0]:
    df = pd.DataFrame(np.arange(n * 100).reshape(-1, 100), columns=mcol)
    for m in sizes.levels[1]:
        cols = np.random.choice(mcol, m, replace=False)
        for f in methods:
            stmt = '{}(df, cols)'.format(f)
            setup = 'from __main__ import {}, df, cols'.format(f)
            tvalue = timeit(stmt, setup, number=500)
            results.set_value((n, m), f, tvalue)

并从每种方法随我们提取的列数增加而发生的情况的角度绘制results图。

fig, axes = plt.subplots(2, 2, figsize=(8, 6))
for i, n in enumerate(sizes.levels[0]):
    ax = axes[i // 2, i % 2]
    results.xs(n).plot(lw=2, ax=ax, title='size {}'.format(n))
    ax.legend().remove()

axes[-1, -1].legend(bbox_to_anchor=(1.7, 2.4), fontsize=10)

fig.suptitle('Num Columns Perspective', fontsize=10)

fig.tight_layout()
plt.subplots_adjust(top=.9)

在此处输入图片说明

然后从增加阵列长度的角度

fig, axes = plt.subplots(3, 2, figsize=(8, 9))
for i, m in enumerate(sizes.levels[1]):
    ax = axes[i // 2, i % 2]
    results.xs(m, level=1).plot(lw=2, ax=ax, title='num cols {}'.format(m), rot=45)
    ax.legend().remove()

axes[-1, -1].legend(bbox_to_anchor=(1.7, 4.1), fontsize=10)

fig.suptitle('Array Length Perspective', fontsize=10)

fig.tight_layout()
plt.subplots_adjust(top=.9)

在此处输入图片说明

这是一种通过将np.searchsorted与给定的字符串索引进行np.searchsorted来获取列整数索引的方法-

def linear_index(df, cols):    
    r,c = df.columns.levels
    d0 = np.array([i[0] for i in cols])
    d1 = np.array([i[1] for i in cols])    

    # Skip getting the argsorts if column names are already sorted
    r_sidx = r.argsort()
    c_sidx = c.argsort()

    return np.searchsorted(r,d0,sorter = r_sidx)*len(c) + \
                        np.searchsorted(c,d1, sorter=c_sidx)

def searchsorted_loc(df, cols):
    return df.values[:, linear_index(df, cols)]

这适用于multi-index数据框。 当处理一级数据帧时,它将简化。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM