【问题标题】:How to group numeric values containing missing data into bins for counting in python如何将包含缺失数据的数值分组到 bin 中以便在 python 中进行计数
【发布时间】:2015-01-24 18:30:24
【问题描述】:

我有一系列整数值,在数据帧(清洁)中缺少数据,我想将其分箱成更大的整数组,然后对这些分箱进行计数(如生成直方图)。这是一个大型数据集,所以我不想通过删除 NaN 来进行子集化。我有这个:

TLag
NaN
2
4
6
8
10
12
14
16
18
20
22

我想要这个:

LagBin  Count
0       4
10      5
20      2

我尝试使用 pd.cut:

tbins=np.arange(0,3600,10)
Clean['LagBin']=pd.cut(Clean['TLag'],bins=tbins,right=True, labels=None,           retbins=False, precision=0, include_lowest=True)

但这会将 LagBin 值作为一个范围返回,并且由于我最终想要绘制它,我真的希望这些 bin 是数字的。另外,当我尝试使用 groupby 函数进行计数时(rx 是另一个将在多索引中的分组变量):

Hist=Clean.groupby(level=('rx','LagBin'))
Hist.count('LagBin')

但这会返回错误:

ValueError: Cannot convert NA to integer 

所以我想我可以使用简单的转换将 Lag 值转换为整数 bin:

Clean['LagBin']=Clean.TLag/10
Clean['LagBin']=(int(Clean.LagBin))*10

我也尝试了 hist() 函数——两者都不起作用,产生了这个错误:

TypeError: cannot convert the series to <type 'float'> 

这似乎是一个非常简单的练习,应该是直截了当的。我错过了什么?

【问题讨论】:

  • 我不明白你想要的输出。你的 LagBin 10 组中不应该有 5 个吗? (10,12,14,16,18)。或者,或者,如果您的间隔是封闭的,那么 0 组中有 5 个?
  • 我想分箱为 10 个(0,10,20...3600)。最终,这是关于产生一个密度函数,我想对其进行进一步的操作。 10 人组是任意的,我希望能够在场合允许时进行转换。好的,我现在明白了这个问题——所以我想我并不真正关心 10 是否包含在内。通常我通过除以 10 ,取整数,然后将该整数乘以 10 来做到这一点,这样我认为是封闭的,对吧? 10/10 是 1*10 是 10,所以 10 进入下一个 bin。
  • 那么鉴于您显示的数据,您的 [4,4,2] 的 Count 列不正确?
  • 叹息。是的。它应该是 4,5,2。我会解决的
  • 在我看来,问题似乎出在 NaN 上。我是 SAS 和 Access 用户,并且是 Python 和 R 的新手,我无法将注意力集中在 sql 中直截了当的任务上(我不想在这里使用 sql,主要是因为我正在努力学习,并且数据框是 12百万条记录 X 17 列)

标签: python pandas group-by histogram


【解决方案1】:

我认为你的想法或多或少是正确的,只是被语法所吸引。例如,我们可以使用除以十乘十的技巧来添加一个LagBin 列,然后在其上添加groupby-count

In [21]: Clean["LagBin"] = (Clean["TLag"]//10)*10

In [22]: Clean
Out[22]: 
    TLag  LagBin
0    NaN     NaN
1      2       0
2      4       0
3      6       0
4      8       0
5     10      10
6     12      10
7     14      10
8     16      10
9     18      10
10    20      20
11    22      20

In [23]: Clean.groupby("LagBin", as_index=False).count()
Out[23]: 
   LagBin  TLag
0       0     4
1      10     5
2      20     2

请注意,我使用// 截断除法,以便2//10 == 02.0//10 == 0(而不是0.2)。

如果您希望更接近您想要的输出,您可以在此处重命名 TLag 或对列本身进行分组:

In [46]: Clean["TLag"].groupby(Clean["LagBin"]).count().reset_index(name="Count")
Out[46]: 
   LagBin  Count
0       0      4
1      10      5
2      20      2

【讨论】:

  • 完美——第一个解决方案效果很好。我不明白 .reset_index() 的目的。你能澄清一下吗?当我运行它时它会抛出一个错误......我的实际代码更复杂,并且数据框已经包含一个多索引。我需要将 LagBin 添加到多索引吗?
  • 在第二个示例中,没有as_index=False,组键(在本例中为箱)用作结果数据帧的索引。我希望将该索引提升为真正的列,并将生成的列命名为 Count
  • 关于多索引的更多信息:TLag 来自不同的接收者(字段名'rx'),我真的想按 rx 分组。所以这就是我输入的内容: Clean['LagBin']=(Clean.TLag//10)*10 arrays = [Clean.rx,Clean.LagBin] # 定义数组对象,其中包含多索引的两个级别index = pd.MultiIndex.from_arrays(arrays, names = ['rx','LagBin']) # 声明多级索引 Clean.index = index
  • @TheodoreCastro-Santos:你在这里还是比较新的 :-) 所以我应该警告你,评论部分并不是我们真正处理后续问题的方式。如果您有单独的问题,请形成一个小示例,人们可以复制和粘贴以使用示例输入和所需输出进行测试,然后打开一个新问题。再加上这样更多的人看到它。
  • 感谢您的提示。但这是一个后续行动......所以我是否将其添加为原始帖子的编辑?
【解决方案2】:

pd.cut函数中尝试labels

tlag = np.arange(0, 30, 2)
tbins = np.arange(0, 100, 10)
pd.value_counts(np.cut(tlag, tbins, labels = tbins[:-1]))

输出是:

Out[136]: 
0     5
10    5
20    4

【讨论】:

    猜你喜欢
    • 2020-02-29
    • 1970-01-01
    • 2020-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-30
    • 2021-10-01
    相关资源
    最近更新 更多