Как пометить кодирование столбца DataFrame, который содержит как числа, так и строки? - PullRequest
1 голос
/ 21 октября 2019

У меня есть этот столбец DataFrame

+-------------------------------------+--+
|                df:                  |  |
+-------------------------------------+--+
| Index           Ticket*             |  |
| 0               254326              |  |
| 1               CA345               |  |
| 3               SA12                |  |
| 4               267891              |  |
| '               '                   |  |
| '               '                   |  |
| '               '                   |  |
| 700            CA356                |  |
+-------------------------------------+--+

Он содержит два вида значений. Некоторые из них являются чистыми числами, а другие представляют собой строки, содержащие буквы и цифры.

Многие строки имеют одинаковые буквы (CA345, CA675 и т. Д.). Я хотел бы сгруппировать и пометить строки одинаковыми буквами с одинаковыми номерами.

Например. Все строки, имеющие «CA», помеченные как 0, все строки, имеющие «SA», помеченные как 1.

Все остальные строки имеют шестизначные числа (без букв). Я хотел бы пометить все такие строки одним и тем же номером (скажем, например, 2)

Ответы [ 2 ]

1 голос
/ 22 октября 2019

1-й подход

Определите пользовательскую функцию, проверьте, содержит ли строка isinstance(val, str) и содержит ли "SA" или "CA"

def label_ticket(row):
    if isinstance(row['Ticket'], str) and 'CA' in row['Ticket']:
        return 0
    if isinstance(row['Ticket'], str) and 'SA' in row['Ticket']:
        return 1
    return 2

Применить пользовательскуюфункция для нового столбца df('Label').

df['Label'] = df.apply(label_ticket, axis=1)
print(df)
     Ticket  Label
0    254326      2
1     CA345      0
2      SA12      1
3    267891      2
700   CA356      0

2-й подход

Если разобраться в ситуации, кажется, вы не представляете, какие экземпляры появятсяв df['Ticket']. В этом случае вы можете использовать re.split(), чтобы найти все строковые шаблоны и соответственно классифицировать их по категориям.

import pandas as pd
import re
df = pd.DataFrame(columns=['Ticket'],
                  data=[[254326],
                        ['CA345'],
                        ['SA12'],
                        [267891],
                        ['CA356']])
df['Pattern'] = df['Ticket'].apply(lambda x: ''.join(re.split("[^a-zA-Z]*", str(x))))
df_label = pd.DataFrame(df['Pattern'].unique(), columns=['Pattern']).reset_index(level=0).rename(columns={'index': 'Label'})
df = df.merge(df_label, how='left')
print(df)

   Ticket Pattern  Label
0  254326              0
1   CA345      CA      1
2    SA12      SA      2
3  267891              0
4   CA356      CA      1
0 голосов
/ 21 октября 2019

У меня недостаточно знаний о Python, но

вы можете попробовать pandas.Series.str.extract

и regular expression

Как:

ptrn=r'(?P<CA>(CA[\d]+))|(?P<SA>(SA[\d]+))|(?P<DIGIT>[\d]{6})'
import pandas as pd
import numpy as np

ls={'tk':[ '254326' ,  'CA345',  'SA12'    ,  '267891'  ,        'CA356' ]}
df = pd.DataFrame(ls)
s=df['tk'].str.extract(ptrn,expand=False)
newDf={0:[x for x in s['CA'] if pd.isnull(x)==False],1:[x for x in s['SA'] if pd.isnull(x)==False],2:[x for x in s['DIGIT'] if pd.isnull(x)==False]}
print(newDf)

выход:

{0: ['CA345', 'CA356'], 1: ['SA12'], 2: ['254326', '267891']}

демо

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