Pandas действие на столбце между двумя числами - PullRequest
2 голосов
/ 06 апреля 2020

В настоящее время используются Pandas и Numpy. У меня есть датафрейм с именем 'df'. Допустим, у меня есть данные ниже, как я могу дать третий столбец значение, основанное на предложении между? Я бы хотел трактовать это как векторизованный подход , если возможно, чтобы сохранить скорость того, что у меня уже есть.

Я пробовал лямбда-функции, но, честно говоря, я не понимаю, что я делаю, и я получаю ошибки, такие как объект не имеет атрибута «между».

Общий подход - использование не векторизованного подхода:

NOTE: I am looking for a way to make this vectorised.

If df.['Col2'] is between 0 and 10
   df.['Col 3'] = 1
Elseif df.['Col2'] is between 10.01 and 20
   df.['Col3']  = 2
Else if df.['Col2'] is between 20.1 and 30
   df.['Col3']  = 3

Набор образцов

+------+------+------+
| Col1 | Col2 | Col3 |
+------+------+------+
| a    |    5 |    1 |
| b    |   10 |    1 |
| c    |   15 |    2 |
| d    |   20 |    2 |
| e    |   25 |    3 |
| f    |   30 |    3 |
| g    |    1 |    1 |
| h    |   11 |    2 |
| i    |   21 |    3 |
| j    |    7 |    1 |
+------+------+------+


Большое спасибо

Ответы [ 4 ]

4 голосов
/ 06 апреля 2020

Решение с повторным использованием вашего текущего кода:

def cust_func(row):
    r = row['Col2']
    if  r >=0 AND r<=10:
        val = 1
    elif r >=10.01 AND r<=20:
        val = 2
    elseif r>=20.01 AND r<=30:
        val = 3
    return val

df['Col3'] = df.apply(cust_func, axis=1)

Оптимальное решение:

cut_labels = [1, 2, 3]
cut_bins = [0, 10, 20,30]
df['Col3'] = pd.cut(df['Col2'], bins=cut_bins, labels=cut_labels)
2 голосов
/ 06 апреля 2020

Существует несколько способов: numpy выбрать и numpy .searchsorted ; я предпочитаю последнее, поскольку мне не нужно перечислять условия - он работает по алгоритму деления на части, пока ваши данные отсортированы; и да, я хотел бы думать, что это самый быстрый из всех. было бы здорово, если бы вы запустили время и поделились результатами:

  Col1  Col2
0   a   5
1   b   10
2   c   15
3   d   20
4   e   25
5   f   30
6   g   1
7   h   11
8   i   21
9   j   7

   #step 1: create ur 'conditions'

#sort dataframe on Col2

df = df.sort_values('Col2')
#benchmarks are ur ranges within which u set ur scores/grade
benchmarks = np.array([10,20,30])

#the grades to be assigned for Col2
score = np.array([1,2,3])

#and use search sorted
#it will generate the indices for where the values should be
#e.g if u have [1,4,5] then the position of 3 will be 1, since it is between 1 and 4
#and python has a zero based index notation
indices = np.searchsorted(benchmarks,df.Col2)

#create ur new column by indexing the score array with the indices
df['Col3'] = score[indices]

df = df.sort_index()

df

    Col1    Col2  Col3
0    a       5      1
1    b       10     1
2    c       15     2
3    d       20     2
4    e       25     3
5    f       30     3
6    g       1      1
7    h       11     2
8    i       21     3
9    j       7      1
1 голос
/ 06 апреля 2020

Вы можете сделать это красиво и чисто с помощью np.select (). Я добавил некоторые <=, потому что я догадался, что вы хотите обновить все значения. Но это легко редактировать, если это необходимо. </p>

conditions = [(df['Col2'] > 0) & (df['Col2'] <= 10),
               (df['Col2'] > 10) & (df['Col2'] <= 20),
               (df['Col2'] > 20) & (df['Col2'] <= 30) ]

updates = [1, 2, 3]

df["Col3"] = np.select(conditions, updates, default=999)

Использование исходного диапазона приведет к этому, где значения == 10, 20, 30 получат значение 999 из np.select ().

conditions = [(df['Col2'] > 0) & (df['Col2'] < 10),
               (df['Col2'] > 10.01) & (df['Col2'] < 20),
               (df['Col2'] > 20.1) & (df['Col2'] < 30) ]

updates = [1, 2, 3]

df["Col3"] = np.select(conditions, updates, default=999)

print(df)

    Col1    Col2    Col3
0   a   5   1
1   b   10  999
2   c   15  2
3   d   20  999
4   e   25  3
5   f   30  999
6   g   1   1
7   h   11  2
8   i   21  3
9   j   7   1
1 голос
/ 06 апреля 2020

Пожалуйста, попробуйте, Boolean выберите

a=df['Col2'].between(0,10)
b=df['Col2'].between(10.01,20)
c=df['Col2'].between(20.1,30)

Применить np.where

import numpy as np
df['Col3']  =np.where(a,1,(np.where(b,2,(np.where(c,3,df['Col3'] )))))

Выход

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...