python - 使用单独的自定义容器(阈值)对 Pandas 列进行分类

标签 python pandas dataframe binning

我有一个 dataframe,其中一些数值存储在 "value" 列中,伴随着它们各自的分类阈值(在本例中为警告级别),存储在其他列中(在我的例子中,“低”“中”“高”):

     value    low  middle    high
0   179.69  17.42   88.87  239.85
1     2.58  17.81   93.37  236.58
2     1.21   0.05    0.01    0.91
3     1.66   0.20    0.32    4.57
4     3.54   0.04    0.04    0.71
5     5.97   0.16    0.17    2.55
6     5.39   0.86    1.62    9.01
7     1.20   0.03    0.01    0.31
8     3.19   0.08    0.01    0.45
9     0.02   0.03    0.01    0.10
10    3.98   0.18    0.05    0.83
11  134.51  78.63  136.86  478.27
12  254.53  83.73  146.33  486.65
13   15.36  86.07   13.74  185.16
14   85.10  86.12   13.74  185.16
15   15.12   1.37    6.09   30.12

我想知道每个值属于哪个类别(例如,第一个值是middle,第二个是below_low,因为它小于它的任何阈值,第三个将是,......你明白了)。所以这是预期的输出:

     value    low  middle    high   category
0   179.69  17.42   88.87  239.85     middle
1     2.58  17.81   93.37  236.58  below_low
2     1.21   0.05    0.01    0.91       high
3     1.66   0.20    0.32    4.57     middle
4     3.54   0.04    0.04    0.71       high
5     5.97   0.16    0.17    2.55       high
6     5.39   0.86    1.62    9.01     middle
7     1.20   0.03    0.01    0.31       high
8     3.19   0.08    0.01    0.45       high
9     0.02   0.03    0.01    0.10     middle
10    3.98   0.18    0.05    0.83       high
11  134.51  78.63  136.86  478.27        low
12  254.53  83.73  146.33  486.65     middle
13   15.36  86.07   13.74  185.16     middle
14   85.10  86.12   13.74  185.16     middle
15   15.12   1.37    6.09   30.12     middle

到目前为止,我使用这种逐行“手动”检查的丑陋程序,停在第一个类别(从高到低),大于当前值:

df["category"]="below_low"    
for i in df.index:
    for cat in ["high","middle","low"]:
        if df.loc[i,"value"]>df.loc[i,cat]:
            df.loc[i,"category"]=cat
            break

我知道 pd.cut() 方法,但我只知道如何将它与预定义的通用阈值列表一起使用。有人能告诉我我错过了什么吗?

最佳答案

您可以使用:

  • 删除列
  • lt比较(少于)
  • 更改列的顺序
  • 累积总和列 - 首先 True 得到 1
  • 通过eq1 比较

mask = df.drop('value',axis=1)
         .lt(df['value'], axis=0)
         .reindex(columns=['high','middle','low'])
         .cumsum(axis=1)
         .eq(1)

如果 highmiddlelow 列中的所有值都是 False,则需要一些正确性。我使用反转的 maskall 创建新列。

mask['below_low'] = (~mask).all(axis=1)
print (mask)
     high middle    low below_low
0    True  False  False     False
1   False  False  False      True
2    True  False  False     False
3   False   True  False     False
4    True  False  False     False
5    True  False  False     False
6   False   True  False     False
7    True  False  False     False
8    True  False  False     False
9   False   True   True     False
10   True  False  False     False
11  False  False   True     False
12  False   True  False     False
13  False   True   True     False
14  False   True   True     False
15  False   True  False     False

上次通话 DataFrame.idxmax :

df['category'] = mask.idxmax(axis=1)
print (df)
     value    low  middle    high   category
0   179.69  17.42   88.87  239.85       high
1     2.58  17.81   93.37  236.58  below_low
2     1.21   0.05    0.01    0.91       high
3     1.66   0.20    0.32    4.57     middle
4     3.54   0.04    0.04    0.71       high
5     5.97   0.16    0.17    2.55       high
6     5.39   0.86    1.62    9.01     middle
7     1.20   0.03    0.01    0.31       high
8     3.19   0.08    0.01    0.45       high
9     0.02   0.03    0.01    0.10     middle
10    3.98   0.18    0.05    0.83       high
11  134.51  78.63  136.86  478.27        low
12  254.53  83.73  146.33  486.65     middle
13   15.36  86.07   13.74  185.16     middle
14   85.10  86.12   13.74  185.16     middle
15   15.12   1.37    6.09   30.12     middle

具有多个 numpy.where 的解决方案正如指出的那样Paul H :

df['category'] = np.where(df['high'] < df['value'], 'high', 
                 np.where(df['middle'] < df['value'], 'medium',
                 np.where(df['low'] < df['value'], 'low', 'below_low')))

print (df)
     value    low  middle    high   category
0   179.69  17.42   88.87  239.85       high
1     2.58  17.81   93.37  236.58  below_low
2     1.21   0.05    0.01    0.91       high
3     1.66   0.20    0.32    4.57     medium
4     3.54   0.04    0.04    0.71       high
5     5.97   0.16    0.17    2.55       high
6     5.39   0.86    1.62    9.01     medium
7     1.20   0.03    0.01    0.31       high
8     3.19   0.08    0.01    0.45       high
9     0.02   0.03    0.01    0.10     medium
10    3.98   0.18    0.05    0.83       high
11  134.51  78.63  136.86  478.27        low
12  254.53  83.73  146.33  486.65     medium
13   15.36  86.07   13.74  185.16     medium
14   85.10  86.12   13.74  185.16     medium
15   15.12   1.37    6.09   30.12     medium

关于python - 使用单独的自定义容器(阈值)对 Pandas 列进行分类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42253069/

相关文章:

python - 根据条件合并行 Pandas 数据框

r - 列表中每个数据帧的最长更改运行时间

python - 从YouTube channel 逐页获取所有视频

python - 如何在 Pandas Dataframe 中合并多个具有相似名称的列而不丢失数据

pandas - Tensorflow:无法为 StringOutputStream 分配大于 kint32max 的缓冲区

python - Pandas 读取从 dataframe.to_string 生成的文本文件

r - 带有 names_pattern 和成对列的 pivot_longer

python - 如何计算另一个列表中列表(作为 pandas 列)中的匹配元素的数量

python - 是否可以在带有可扩展选项的推送通知中发送 Firebase(FCM)通知消息(多行消息);使用Python?

json - 在 FastAPI 应用程序中将 JSON 转换为 DataFrame