gpt4 book ai didi

python - 为什么使用 pandas qcut 返回 ValueError : Bin edges must be unique?

转载 作者:太空狗 更新时间:2023-10-30 00:54:35 31 4
gpt4 key购买 nike

我有数据集:

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' 有超过 28% 的数字为 1。这破坏了 qcut

我提供了一个新函数 pct_rank_qcut 来解决这个问题并将所有 1 插入第一个 bin。

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

此行根据 n 定义的所需 bin 数量定义了一系列百分位数边缘。在 n = 5 的情况下,边缘将为 [0.0, 0.2, 0.4, 0.6, 0.8, 1.0]

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

此行定义了一个辅助函数,该函数将应用于下一行中的另一个系列。 edges >= x 将返回长度等于 edges 的系列,其中每个元素为 TrueFalse,具体取决于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 的 bin 编号。这一系列的 bin 编号与您试图获得的相同:

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

这会导致 bin 不再相等并且 bin 1 完全从 bin 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)

关于python - 为什么使用 pandas qcut 返回 ValueError : Bin edges must be unique?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36880490/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com