Как я могу изменить данные столбца pandas в соответствии с заданным условием c на основе записи столбца? - PullRequest
1 голос
/ 13 июля 2020

У меня есть такой фрейм данных:

    MONTH   TIME     PATH    RATE
0    Feb  15:24:11  enp1s0  14.71Kb  

Я хочу создать функцию, которая может определять, находится ли «Кбайт» или «Мбайт» в столбце RATE. Если запись в столбце RATE имеет в конце «Кбайт» или «Мбайт», чтобы убрать из нее «Кбайт» / «Мбайт» и выполнить операцию по преобразованию в просто b. Вот мой код, где RATE обрабатывается Dataframe как объект:

df=pd.DataFrame(listOfLists)
def strip(bytesData):
        if "Kb" in bytesData:
                bytesData/1000
        elif "Mb" in bytesData:
                bytesData/1000000

df['RATE']=df.apply(lambda x: strip(x['byteData']), axis=1)

Как я могу заставить его изменить значение в столбце, удаляя ненужные символы и преобразовывая его в формат I необходимость? Я знаю, что после завершения этой операции мне придется изменить его на int, однако я не могу изменить данные так, как мне нужно. Заранее спасибо!

Ответы [ 2 ]

1 голос
/ 13 июля 2020

Вот как я могу подойти к этому. Это решение обрабатывает другие сокращения. Однако он полагается на стандартный пакет библиотеки regex re.

Этот подход создает новый столбец с именем Bytes. Я часто считаю полезным оставить столбец RATE в этом случае, чтобы убедиться, что нет никаких крайних случаев, о которых я не думал. Я также использую сопоставление, чтобы получить необходимую мощность для повышения значения, чтобы получить правильные байты. Я добавил код, необходимый для удаления исходного столбца RATE и переименования нового столбца.

import re

def convert_to_bytes(contents):
    value, label, _ = re.split('([A-Za-z]+)', contents)
    factors = {'Kb': 1, 'Mb': 2, 'Gb': 3, 'Tb': 4}
    return float(value) * 1000**(factors[label])

df['Bytes'] = df['RATE'].map(convert_to_bytes)

# Drop original RATE column
df = df.drop('RATE', axis=1)
# Rename Bytes column to RATE
df = df.rename({'Bytes': 'RATE'}, axis='columns')
1 голос
/ 13 июля 2020

Я немного изменил вашу функцию и использовал map(lambda x:) вместо apply, поскольку мы работаем с серией, а не с полным фреймом данных. Также я добавил несколько дополнительных строк, чтобы предоставить примеры как для КБ, так и для МБ, и если ни один из них не присутствует:

example_df = pd.DataFrame({'Month':[0,1,2,3],
                           'Time':['15:32','16:42','17:11','15:21'],
                           'Path':['xxxxx','yyyyy','zzzzz','aaaaa'],
                           'Rate':['14.71Kb','18.21Mb','19.01Kb','Error_1']})
def case_1(value):
  if value[-2:] == 'Kb':
    return float(value[:-2])*1000
  elif value[-2:] == 'Mb':
    return float(value[:-2])*100000
  else:
    return np.nan
example_df['Rate'] = example_df['Rate'].map(lambda x: case_1(x))

Лог c для функции, если он заканчивается на Kb, умножьте значение на 1000, иначе - если оно заканчивается на Mb, умножьте значение на 100000, в противном случае просто верните NaN (потому что ни одно из двух условий не выполняется). Вывод:

   Month   Time   Path       Rate
0      0  15:32  xxxxx    14710.0
1      1  16:42  yyyyy  1821000.0
2      2  17:11  zzzzz    19010.0
3      3  15:21  aaaaa        NaN
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...