当前位置: 首页 > 面试题库 >

为什么要使用熊猫qcut返回ValueError:Bin边缘必须唯一?

刘选
2023-03-14
问题内容

我有数据集:

recency;frequency;monetary
21;156;41879955
13;88;16850284
8;74;79150488
2;74;26733719
9;55;16162365
...;...;...

详细原始数据-> http://pastebin.com/beiEeS80
,我放入其中DataFrame,这是我完整的代码

df = pd.DataFrame(datas, columns=['userid', 'recency', 'frequency', 'monetary'])
df['recency'] = df['recency'].astype(float)
df['frequency'] = df['frequency'].astype(float)
df['monetary'] = df['monetary'].astype(float)

df['recency'] = pd.qcut(df['recency'].values, 5).codes + 1
df['frequency'] = pd.qcut(df['frequency'].values, 5).codes + 1
df['monetary'] = pd.qcut(df['monetary'].values, 5).codes + 1

但这是返回错误

df['frequency'] = pd.qcut(df['frequency'].values, 5).codes + 1
ValueError: Bin edges must be unique: array([   1.,    1.,    2.,    4.,    9.,  156.])

如何解决呢?


问题答案:

我在Jupyter中运行了此文件,并将exampledata.txt放置在与笔记本相同的目录中。

请注意第一行:

df = pd.DataFrame(datas, columns=['userid', 'recency', 'frequency', 'monetary'])

'userid'未在数据文件中定义时加载列。我删除了此列名。

import pandas as pd

def pct_rank_qcut(series, n):
    edges = pd.Series([float(i) / n for i in range(n + 1)])
    f = lambda x: (edges >= x).argmax()
    return series.rank(pct=1).apply(f)

datas = pd.read_csv('./exampledata.txt', delimiter=';')

df = pd.DataFrame(datas, columns=['recency', 'frequency', 'monetary'])

df['recency'] = df['recency'].astype(float)
df['frequency'] = df['frequency'].astype(float)
df['monetary'] = df['monetary'].astype(float)

df['recency'] = pct_rank_qcut(df.recency, 5)
df['frequency'] = pct_rank_qcut(df.frequency, 5)
df['monetary'] = pct_rank_qcut(df.monetary, 5)

说明

您看到的问题是pd.qcut的结果,假设5个bin大小相等。在您提供的数据中,'frequency'数字1超过28%。这打破了qcut

我提供了一个新功能pct_rank_qcut来解决此问题,并将所有1推入第一个bin。

    edges = pd.Series([float(i) / n for i in range(n + 1)])

这条线基于定义的bin的所需数量定义了一系列百分比边缘n。在n = 5边缘的情况下[0.0, 0.2, 0.4, 0.6, 0.8, 1.0]

    f = lambda x: (edges >= x).argmax()

该行定义了辅助功能,该功能将应用于下一行中的另一个系列。 edges >= x将返回一个长度相等于edges每个元素所在位置的序列,True或者False取决于是否x小于或等于该边缘。在x = 0.14结果(edges >= x)将为的情况下[False, True, True, True, True, True]。通过这种情况,在这种情况下,argmax()我已经确定了系列的第一个索引。True``1

    return series.rank(pct=1).apply(f)

该行接受输入series并将其转换为百分等级。我可以将这些排名与创建的边缘进行比较,这就是为什么要使用的原因apply(f)。返回的应该是一系列从1到n的箱号。这一系列的箱号与您尝试获得的相同:

pd.qcut(df['recency'].values, 5).codes + 1

结果是仓不再相等,仓1完全从仓2借用。但是必须做出一些选择。如果您不喜欢这种选择,请使用此概念来建立自己的排名。

示范

print df.head()

   recency  frequency  monetary
0        3          5         5
1        2          5         5
2        2          5         5
3        1          5         5
4        2          5         5

更新资料

pd.Series.argmax()现在已弃用。只需切换pd.Series.values.argmax()()至更新!

def pct_rank_qcut(series, n):
    edges = pd.Series([float(i) / n for i in range(n + 1)])
    f = lambda x: (edges >= x).values.argmax()
    return series.rank(pct=1).apply(f)


 类似资料:
  • 我只是不明白第二行“==”的意思: -这不是一个测试,没有if语句… -它不是一个变量声明。。。 我以前从未见过这个,事情是是熊猫系列,而不是测试...

  • C++20概念的一个特点是,在某些情况下,您必须编写。例如,[expr.prim.req]/3中的这个示例:

  • 问题内容: 我的动机是利用熊猫功能来进行滚动多因素回归(这个问题是 不是 关于滚动多因素回归)。我希望我可以在a之后使用,并使用所得结果提取ndarray并执行必要的矩阵乘法。那样行不通。 这是我发现的: 对象是什么样的: 矩阵乘法的行为正常: 使用Apply执行逐行点积的行为符合预期: Groupby-> Apply的行为符合我的预期: 但是当我跑步时: 我得到: AttributeError:

  • 根据文档,newInstance()返回一个T:https://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#newInstance() 所以,如果我有一个返回T的方法,为什么我必须强制转换构造函数的返回。newInstance()到T?

  • 问题内容: 即使等待1的linux手册页很好地说明了您需要让子进程不使其变成僵尸,但它根本无法说明原因。 我围绕一个Ever 循环计划了我的程序(这是我的第一个多线程程序,所以请原谅我的天真),该循环启动子进程,该子进程被ed淘汰,并确保自行终止。 我无法使用,因为这使并行计算变得不可能,因此我可能不得不添加一个存储子pid的进程表,并且不得不使用-不是立即执行,而是经过一段时间- 这是一个问题,

  • 关于在最新版本的GCC和Clang中编译有几个问题:实验::filessystems链接器错误 但是现在< code>filesystem已经被c 17接受,所以不再需要< code>experimental或< code>-lstdc fs标志,对吗? 错了,我甚至不能 只给了我< code >实验版本,我怎么能包括正式接受的版本呢?