获取具有任何所需值的组
Posted
技术标签:
【中文标题】获取具有任何所需值的组【英文标题】:get groups with any of desired values 【发布时间】:2018-12-11 19:54:50 【问题描述】:gr = []
for i in range(12000): gr.extend([i] * 2)
np.random.seed(0)
df = pd.DataFrame('gr': gr,
'col1': np.random.choice(200, 24000))
anyOfThese = np.array([50, 60]) #randomly chosen
t = time()
out = df[df.groupby('gr')['col1'].transform(lambda x: np.any(np.in1d(np.array(x), anyOfThese))).astype(bool)].gr.unique()
print(round(time() - t,2))
>>> 1.87
我需要在col1
中获取具有两个所需值中的任何一个的所有组。
有没有办法更快地实现这一目标?我需要重复相同的过程〜100k次。
【问题讨论】:
【参考方案1】:使用boolean indexing
过滤isin
:
out = df.loc[df['col1'].isin(anyOfThese), 'gr'].unique()
或通过numpy.in1d
查看会员:
out = df.loc[np.in1d(df['col1'], anyOfThese), 'gr'].unique()
时间安排:
np.random.seed(218)
gr = []
for i in range(12000):
gr.extend([i] * 2)
np.random.seed(0)
df = pd.DataFrame('gr': gr,
'col1': np.random.choice(200, 24000))
anyOfThese = np.array([50, 60]) #randomly chosen
a = df[df.groupby('gr')['col1'].transform(lambda x: np.any(np.in1d(np.array(x), anyOfThese))).astype(bool)].gr.unique()
out = df.loc[df['col1'].isin(anyOfThese), 'gr'].unique()
print ((a == out).all())
True
In [314]: %timeit df[df.groupby('gr')['col1'].transform(lambda x: np.any(np.in1d(np.array(x), anyOfThese))).astype(bool)].gr.unique()
2.9 s ± 79.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [315]: %timeit df.loc[df['col1'].isin(anyOfThese), 'gr'].unique()
746 µs ± 32.6 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
In [316]: %timeit df.loc[np.in1d(df['col1'], anyOfThese), 'gr'].unique()
325 µs ± 14.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
【讨论】:
令人惊讶的是,有时会忽略简单性,而事情会无缘无故地变得过于复杂【参考方案2】:对于较大的数组,如果您只有 2 个值,您可以检查每个值是否相等并使用 |
(或)条件:
%timeit df.loc[(df['col1'].values == 50) | (df['col1'].values == 60), 'gr'].unique()
%timeit df.loc[np.in1d(df['col1'], anyOfThese), 'gr'].unique()
1000 loops, best of 3: 1.07 ms per loop
1000 loops, best of 3: 1.13 ms per loop
在 Numpy 1.11.3 / Pandas 0.19.2 / Python 3.6.0 上测试。性能可能因您的设置而异。用于测试的代码:
gr = []
for i in range(120000): gr.extend([i] * 2)
np.random.seed(0)
df = pd.DataFrame('gr': gr,
'col1': np.random.choice(200, 240000))
anyOfThese = np.array([50, 60])
%timeit df.loc[(df['col1'].values == 50) | (df['col1'].values == 60), 'gr'].unique()
%timeit df.loc[np.in1d(df['col1'], anyOfThese), 'gr'].unique()
【讨论】:
以上是关于获取具有任何所需值的组的主要内容,如果未能解决你的问题,请参考以下文章