![](/img/trans.png)
[英]What is the fastest way to conditionally change the values of a dataframe in every index and column?
[英]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.