【问题标题】:Pandas - assign histogram bucket to each rowPandas - 将直方图桶分配给每一行
【发布时间】:2016-11-23 20:43:43
【问题描述】:

这是我的数据框:

import pandas as pd
df = pd.DataFrame({'A': [1, 2, 3, 4, 6, 4, 3, 2, 7]})
buckets = [(0,3),(3,5),(5,9)]

我也有上面提到的直方图桶。现在我想将每一行数据帧分配给存储桶索引。所以我想获得包含以下信息的新专栏:

df['buckets_index']  = [0,0,0,1,2,1,0,0,2]

当然,我可以使用循环来完成,但我有相当大的数据框(250 万行),所以我需要快速完成。

有什么想法吗?

【问题讨论】:

  • 桶的限制是否会使得前一个桶的结尾总是与下一个桶的开始相同?
  • @Divakar,谢谢你的好问题。区间从左开右闭(0,3], (3,5], (5,9],是的,限制很常见。
  • df.A 中是否有任何元素不在任何存储桶中,即超出存储桶限制?
  • @Divakar 这是可能的。
  • 那么,这些输出的预期输出是什么?添加此类案例的示例?

标签: python performance pandas histogram vectorization


【解决方案1】:

如果你只想要索引,你可以使用pd.cut,和labels=False

buckets = [0,3,5,9]
df['bucket'] = pd.cut(df['A'], bins=buckets)
df['bucket_idx'] = pd.cut(df['A'], bins=buckets, labels=False)

结果输出:

   A  bucket  bucket_idx
0  1  (0, 3]           0
1  2  (0, 3]           0
2  3  (0, 3]           0
3  4  (3, 5]           1
4  6  (5, 9]           2
5  4  (3, 5]           1
6  3  (0, 3]           0
7  2  (0, 3]           0
8  7  (5, 9]           2

【讨论】:

  • 如果需要,您可以添加.cat.codes 来获取整数,而不是分类dtype
【解决方案2】:

你可以使用np.searchsorted -

df['buckets_index'] = np.asarray(buckets)[:,1].searchsorted(df.A.values)

运行时测试-

In [522]: df = pd.DataFrame({'A': np.random.randint(1,8,(10000))})

In [523]: buckets = [0,3,5,9]

In [524]: %timeit pd.cut(df['A'], bins=buckets, labels=False)
1000 loops, best of 3: 460 µs per loop # @root's soln

In [525]: buckets = [(0,3),(3,5),(5,9)]

In [526]: %timeit np.asarray(buckets)[:,1].searchsorted(df.A.values)
10000 loops, best of 3: 166 µs per loop

超限情况:对于这种情况,我们需要使用裁剪,像这样-

np.asarray(buckets)[:,1].searchsorted(df.A.values).clip(max=len(buckets)-1)

【讨论】:

  • 您和 root 的解决方案都给我留下了深刻的印象。我希望我能把你的两个答案都算作正确的。我会回答root,因为他的等级较低。我希望你不介意。
  • @user1700890 当然,没关系! :)
猜你喜欢
  • 2015-10-11
  • 2018-08-23
  • 1970-01-01
  • 2020-05-11
  • 2018-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-13
相关资源
最近更新 更多