python - 基于多列分箱(分类值)的最佳方式

标签 python python-3.x pandas dataframe

我需要将两列中的值合并到另一列中。

假设以下是我的 pandas df:

data = {'material':['Matl_A', 'Matl_B', 'Matl_B', 'Matl_A'], 
        'strength':[10, 20, 30, 100]  
df = pd.DataFrame(data)

所以我的 df 是:

  material   strength  
 ---------- ---------- 
  Matl_A           10  
  Matl_B           20  
  Matl_B           30  
  Matl_A          100  

我想做这样的事情:

  material   strength    grade
 ---------- ---------- ---------
  Matl_A           10       1
  Matl_B           20       4
  Matl_B           80       5
  Matl_A          100       2

执行此操作的最佳方法是什么?

编辑:

我在下面使用了 Michael Gardner 的回答并对其进行了扩展,因为我们有很多 Material 。希望这次修订能提供更清晰的画面。如果我需要对 20 种具有不同条件范围的 Material 进行分类,那么更优雅的方法是什么:

    import numpy as np
    import pandas as pd

    strength = np.random.randint(low=1, high=30, size=20)
    material = ['matl_a', 'matl_b', 'matl_b', 'matl_a', 'matl_d',
                'matl_b', 'matl_d', 'matl_a', 'matl_a', 'matl_b',
                'matl_a', 'matl_b', 'matl_e', 'matl_a', 'matl_c',
                'matl_b', 'matl_c', 'matl_a', 'matl_a', 'matl_b']

    data = {'material':material, 
            'strength':strength } 
    df = pd.DataFrame(data)

    def grading(df):
        if df['material'] == 'matl_a':
            if 0 <= df['strength'] <=10:
                return 1
            elif 11 <= df['strength'] <= 20:
                return 2
            elif 21 <= df['strength'] <= 30:
                return 3
            elif 31 <= df['strength'] <= 40:
                return 4
            else:
                return 5
        elif df['material'] == 'matl_b':
            if 0 <= df['strength'] <=10:
                return 6
            elif 11 <= df['strength'] <= 20:
                return 7
            elif 21 <= df['strength'] <= 30:
                return 8
            elif 31 <= df['strength'] <= 40:
                return 9
            else:
                return 10
        elif df['material'] == 'matl_c':
            if 0 <= df['strength'] <=10:
                return 11
            elif 11 <= df['strength'] <= 20:
                return 12
            elif 21 <= df['strength'] <= 30:
                return 13
            elif 31 <= df['strength'] <= 40:
                return 14
            else:
                return 15        
        else:
            if 0 <= df['strength'] <=10:
                return 16
            elif 11 <= df['strength'] <= 20:
                return 17
            elif 21 <= df['strength'] <= 30:
                return 18
            elif 31 <= df['strength'] <= 40:
                return 19
            else:
                return 20

    df['grade'] = df.apply(grading, axis=1)

最佳答案

使用np.select

a = df.material.eq('Matl_A')
b = df.material.eq('Matl_B')

df['grade'] = np.select([a & df.strength.between(5,10),
                         a & df.strength.between(11,20),
                         b & df.strength.between(10,50),
                         b & df.strength.between(50,100)],
                         ['A', 'B', 'A', 'B'],
                         default='C')

关于python - 基于多列分箱(分类值)的最佳方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57916603/

相关文章:

python - 如果指定列中的标志(匹配前 6 个字母)是 "1",将数据转换为 NaN 的方法是什么?

在 Windows 操作系统中计算大文件的 SHA1 哈希值时 Python 崩溃

Visual Studio Code 中的 Python3 Linting

python - pandas如何忽略无法转换为日期时间以计算时间增量的列单元格

python-3.x - 如何使用 Selenium (Python) 抓取多个页面

python - 如何根据另一列减少数据框列值的一部分

pandas - 检测特定 Pandas 列类型的pythonic方法

python - pandas:drop 缺失率超过 90% 的列

python - OpenCV 4.0.0 系统错误 : <class 'cv2.CascadeClassifier' > returned a result with an error set

python - python的控制台应用程序gui